diff options
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java | 923 |
1 files changed, 0 insertions, 923 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java deleted file mode 100644 index 1720caf0e..000000000 --- a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java +++ /dev/null @@ -1,923 +0,0 @@ -/** - * Copyright 2010-2023 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package com.jogamp.opengl.math.geom; - -import com.jogamp.graph.geom.plane.AffineTransform; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.Matrix4f; -import com.jogamp.opengl.math.Quaternion; -import com.jogamp.opengl.math.Ray; -import com.jogamp.opengl.math.Recti; -import com.jogamp.opengl.math.Vec3f; -import com.jogamp.opengl.util.PMVMatrix; - - -/** - * Axis Aligned Bounding Box. Defined by two 3D coordinates (low and high) - * The low being the the lower left corner of the box, and the high being the upper - * right corner of the box. - * <p> - * A few references for collision detection, intersections: - * <pre> - * http://www.realtimerendering.com/intersections.html - * http://www.codercorner.com/RayAABB.cpp - * http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter0.htm - * http://realtimecollisiondetection.net/files/levine_swept_sat.txt - * </pre> - * </p> - * - */ -public class AABBox { - private static final boolean DEBUG = FloatUtil.DEBUG; - private final Vec3f low = new Vec3f(); - private final Vec3f high = new Vec3f(); - private final Vec3f center = new Vec3f(); - - /** - * Create an Axis Aligned bounding box (AABBox) with the - * inverse low/high, allowing the next {@link #resize(float, float, float)} command to hit. - * <p> - * The dimension, i.e. {@link #getWidth()} abd {@link #getHeight()} is {@link Float#isInfinite()} thereafter. - * </p> - * @see #reset() - */ - public AABBox() { - reset(); - } - - /** - * Create an AABBox copying all values from the given one - * @param src the box value to be used for the new instance - */ - public AABBox(final AABBox src) { - copy(src); - } - - /** - * Create an AABBox specifying the coordinates - * of the low and high - * @param lx min x-coordinate - * @param ly min y-coordnate - * @param lz min z-coordinate - * @param hx max x-coordinate - * @param hy max y-coordinate - * @param hz max z-coordinate - */ - public AABBox(final float lx, final float ly, final float lz, - final float hx, final float hy, final float hz) { - setSize(lx, ly, lz, hx, hy, hz); - } - - /** - * Create a AABBox defining the low and high - * @param low min xyz-coordinates - * @param high max xyz-coordinates - */ - public AABBox(final float[] low, final float[] high) { - setSize(low, high); - } - - /** - * Create a AABBox defining the low and high - * @param low min xyz-coordinates - * @param high max xyz-coordinates - */ - public AABBox(final Vec3f low, final Vec3f high) { - setSize(low, high); - } - - /** - * Resets this box to the inverse low/high, allowing the next {@link #resize(float, float, float)} command to hit. - * <p> - * The dimension, i.e. {@link #getWidth()} abd {@link #getHeight()} is {@link Float#isInfinite()} thereafter. - * </p> - * @return this AABBox for chaining - */ - public final AABBox reset() { - setLow(Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE); - setHigh(-1*Float.MAX_VALUE,-1*Float.MAX_VALUE,-1*Float.MAX_VALUE); - center.set( 0f, 0f, 0f); - return this; - } - - /** Get the max xyz-coordinates - * @return max xyz coordinates - */ - public final Vec3f getHigh() { - return high; - } - - private final void setHigh(final float hx, final float hy, final float hz) { - this.high.set(hx, hy, hz); - } - - /** Get the min xyz-coordinates - * @return min xyz coordinates - */ - public final Vec3f getLow() { - return low; - } - - private final void setLow(final float lx, final float ly, final float lz) { - this.low.set(lx, ly, lz); - } - - private final void computeCenter() { - center.set(high).add(low).scale(1f/2f); - } - - /** - * Copy given AABBox 'src' values to this AABBox. - * - * @param src source AABBox - * @return this AABBox for chaining - */ - public final AABBox copy(final AABBox src) { - low.set(src.low); - high.set(src.high); - center.set(src.center); - return this; - } - - /** - * Set size of the AABBox specifying the coordinates - * of the low and high. - * - * @param low min xyz-coordinates - * @param high max xyz-coordinates - * @return this AABBox for chaining - */ - public final AABBox setSize(final float[] low, final float[] high) { - return setSize(low[0],low[1],low[2], high[0],high[1],high[2]); - } - - /** - * Set size of the AABBox specifying the coordinates - * of the low and high. - * - * @param lx min x-coordinate - * @param ly min y-coordnate - * @param lz min z-coordinate - * @param hx max x-coordinate - * @param hy max y-coordinate - * @param hz max z-coordinate - * @return this AABBox for chaining - */ - public final AABBox setSize(final float lx, final float ly, final float lz, - final float hx, final float hy, final float hz) { - this.low.set(lx, ly, lz); - this.high.set(hx, hy, hz); - computeCenter(); - return this; - } - - /** - * Set size of the AABBox specifying the coordinates - * of the low and high. - * - * @param low min xyz-coordinates - * @param high max xyz-coordinates - * @return this AABBox for chaining - */ - public final AABBox setSize(final Vec3f low, final Vec3f high) { - this.low.set(low); - this.high.set(high); - computeCenter(); - return this; - } - - /** - * Resize width of this AABBox with explicit left- and right delta values - * @param deltaLeft positive value will shrink width, otherwise expand width - * @param deltaRight positive value will expand width, otherwise shrink width - * @return this AABBox for chaining - */ - public final AABBox resizeWidth(final float deltaLeft, final float deltaRight) { - boolean mod = false; - if( !FloatUtil.isZero(deltaLeft) ) { - low.setX( low.x() + deltaLeft ); - mod = true; - } - if( !FloatUtil.isZero(deltaRight) ) { - high.setX( high.x() + deltaRight ); - mod = true; - } - if( mod ) { - computeCenter(); - } - return this; - } - - /** - * Resize height of this AABBox with explicit bottom- and top delta values - * @param deltaBottom positive value will shrink height, otherwise expand height - * @param deltaTop positive value will expand height, otherwise shrink height - * @return this AABBox for chaining - */ - public final AABBox resizeHeight(final float deltaBottom, final float deltaTop) { - boolean mod = false; - if( !FloatUtil.isZero(deltaBottom) ) { - low.setY( low.y() + deltaBottom ); - mod = true; - } - if( !FloatUtil.isZero(deltaTop) ) { - high.setY( high.y() + deltaTop ); - mod = true; - } - if( mod ) { - computeCenter(); - } - return this; - } - - /** - * Assign values of given AABBox to this instance. - * - * @param o source AABBox - * @return this AABBox for chaining - */ - public final AABBox set(final AABBox o) { - this.low.set(o.low); - this.high.set(o.high); - this.center.set(o.center); - return this; - } - - /** - * Resize the AABBox to encapsulate another AABox - * @param newBox AABBox to be encapsulated in - * @return this AABBox for chaining - */ - public final AABBox resize(final AABBox newBox) { - final Vec3f newLow = newBox.getLow(); - final Vec3f newHigh = newBox.getHigh(); - - /** test low */ - if (newLow.x() < low.x()) { - low.setX( newLow.x() ); - } - if (newLow.y() < low.y()) { - low.setY( newLow.y() ); - } - if (newLow.z() < low.z()) { - low.setZ( newLow.z() ); - } - - /** test high */ - if (newHigh.x() > high.x()) { - high.setX( newHigh.x() ); - } - if (newHigh.y() > high.y()) { - high.setY( newHigh.y() ); - } - if (newHigh.z() > high.z()) { - high.setZ( newHigh.z() ); - } - computeCenter(); - return this; - } - - /** - * Resize the AABBox to encapsulate another AABox, which will be <i>transformed</i> on the fly first. - * @param newBox AABBox to be encapsulated in - * @param t the {@link AffineTransform} applied on <i>newBox</i> on the fly - * @param tmpV3 temporary storage - * @return this AABBox for chaining - */ - public final AABBox resize(final AABBox newBox, final AffineTransform t, final Vec3f tmpV3) { - /** test low */ - { - final Vec3f newBoxLow = newBox.getLow(); - t.transform(newBoxLow, tmpV3); - if (tmpV3.x() < low.x()) - low.setX( tmpV3.x() ); - if (tmpV3.y() < low.y()) - low.setY( tmpV3.y() ); - if (tmpV3.z() < low.z()) - low.setZ( tmpV3.z() ); - } - - /** test high */ - { - final Vec3f newBoxHigh = newBox.getHigh(); - t.transform(newBoxHigh, tmpV3); - if (tmpV3.x() > high.x()) - high.setX( tmpV3.x() ); - if (tmpV3.y() > high.y()) - high.setY( tmpV3.y() ); - if (tmpV3.z() > high.z()) - high.setZ( tmpV3.z() ); - } - - computeCenter(); - return this; - } - - /** - * Resize the AABBox to encapsulate the passed - * xyz-coordinates. - * @param x x-axis coordinate value - * @param y y-axis coordinate value - * @param z z-axis coordinate value - * @return this AABBox for chaining - */ - public final AABBox resize(final float x, final float y, final float z) { - /** test low */ - if (x < low.x()) { - low.setX( x ); - } - if (y < low.y()) { - low.setY( y ); - } - if (z < low.z()) { - low.setZ( z ); - } - - /** test high */ - if (x > high.x()) { - high.setX( x ); - } - if (y > high.y()) { - high.setY( y ); - } - if (z > high.z()) { - high.setZ( z ); - } - - computeCenter(); - return this; - } - - /** - * Resize the AABBox to encapsulate the passed - * xyz-coordinates. - * @param xyz xyz-axis coordinate values - * @param offset of the array - * @return this AABBox for chaining - */ - public final AABBox resize(final float[] xyz, final int offset) { - return resize(xyz[0+offset], xyz[1+offset], xyz[2+offset]); - } - - /** - * Resize the AABBox to encapsulate the passed - * xyz-coordinates. - * @param xyz xyz-axis coordinate values - * @return this AABBox for chaining - */ - public final AABBox resize(final float[] xyz) { - return resize(xyz[0], xyz[1], xyz[2]); - } - - /** - * Resize the AABBox to encapsulate the passed - * xyz-coordinates. - * @param xyz xyz-axis coordinate values - * @return this AABBox for chaining - */ - public final AABBox resize(final Vec3f xyz) { - return resize(xyz.x(), xyz.y(), xyz.z()); - } - - /** - * Check if the x & y coordinates are bounded/contained - * by this AABBox - * @param x x-axis coordinate value - * @param y y-axis coordinate value - * @return true if x belong to (low.x, high.x) and - * y belong to (low.y, high.y) - */ - public final boolean contains(final float x, final float y) { - if(x<low.x() || x>high.x()){ - return false; - } - if(y<low.y()|| y>high.y()){ - return false; - } - return true; - } - - /** - * Check if the xyz coordinates are bounded/contained - * by this AABBox. - * @param x x-axis coordinate value - * @param y y-axis coordinate value - * @param z z-axis coordinate value - * @return true if x belong to (low.x, high.x) and - * y belong to (low.y, high.y) and z belong to (low.z, high.z) - */ - public final boolean contains(final float x, final float y, final float z) { - if(x<low.x() || x>high.x()){ - return false; - } - if(y<low.y()|| y>high.y()){ - return false; - } - if(z<low.z() || z>high.z()){ - return false; - } - return true; - } - - /** - * Check if there is a common region between this AABBox and the passed - * 2D region irrespective of z range - * @param x lower left x-coord - * @param y lower left y-coord - * @param w width - * @param h hight - * @return true if this AABBox might have a common region with this 2D region - */ - public final boolean intersects2DRegion(final float x, final float y, final float w, final float h) { - if (w <= 0 || h <= 0) { - return false; - } - - final float _w = getWidth(); - final float _h = getHeight(); - if (_w <= 0 || _h <= 0) { - return false; - } - - final float x0 = getMinX(); - final float y0 = getMinY(); - return (x >= x0 && - y >= y0 && - x + w <= x0 + _w && - y + h <= y0 + _h); - } - - /** - * Check if {@link Ray} intersects this bounding box. - * <p> - * Versions uses the SAT[1], testing 6 axes. - * Original code for OBBs from MAGIC. - * Rewritten for AABBs and reorganized for early exits[2]. - * </p> - * <pre> - * [1] SAT = Separating Axis Theorem - * [2] http://www.codercorner.com/RayAABB.cpp - * </pre> - * @param ray - * @return - */ - public final boolean intersectsRay(final Ray ray) { - // diff[XYZ] -> VectorUtil.subVec3(diff, ray.orig, center); - // ext[XYZ] -> extend VectorUtil.subVec3(ext, high, center); - - final float dirX = ray.dir.x(); - final float diffX = ray.orig.x() - center.x(); - final float extX = high.x() - center.x(); - if( Math.abs(diffX) > extX && diffX*dirX >= 0f ) return false; - - final float dirY = ray.dir.y(); - final float diffY = ray.orig.y() - center.y(); - final float extY = high.y() - center.y(); - if( Math.abs(diffY) > extY && diffY*dirY >= 0f ) return false; - - final float dirZ = ray.dir.z(); - final float diffZ = ray.orig.z() - center.z(); - final float extZ = high.z() - center.z(); - if( Math.abs(diffZ) > extZ && diffZ*dirZ >= 0f ) return false; - - final float absDirY = Math.abs(dirY); - final float absDirZ = Math.abs(dirZ); - - float f = dirY * diffZ - dirZ * diffY; - if( Math.abs(f) > extY*absDirZ + extZ*absDirY ) return false; - - final float absDirX = Math.abs(dirX); - - f = dirZ * diffX - dirX * diffZ; - if( Math.abs(f) > extX*absDirZ + extZ*absDirX ) return false; - - f = dirX * diffY - dirY * diffX; - if( Math.abs(f) > extX*absDirY + extY*absDirX ) return false; - - return true; - } - - /** - * Return intersection of a {@link Ray} with this bounding box, - * or null if none exist. - * <p> - * <ul> - * <li>Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990 [2]</li> - * <li>Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)</li> - * <li>Epsilon value added by Klaus Hartmann.</li> - * </ul> - * </p> - * <p> - * Method is based on the requirements: - * <ul> - * <li>the integer representation of 0.0f is 0x00000000</li> - * <li>the sign bit of the float is the most significant one</li> - * </ul> - * </p> - * <p> - * Report bugs: [email protected] (original author) - * </p> - * <pre> - * [1] http://www.codercorner.com/RayAABB.cpp - * [2] http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c - * </pre> - * @param result vec3 - * @param ray - * @param epsilon - * @param assumeIntersection if true, method assumes an intersection, i.e. by pre-checking via {@link #intersectsRay(Ray)}. - * In this case method will not validate a possible non-intersection and just computes - * coordinates. - * @return float[3] result of intersection coordinates, or null if none exists - */ - public final Vec3f getRayIntersection(final Vec3f result, final Ray ray, final float epsilon, - final boolean assumeIntersection) { - final float[] maxT = { -1f, -1f, -1f }; - - final Vec3f origin = ray.orig; - final Vec3f dir = ray.dir; - - boolean inside = true; - - // Find candidate planes. - for(int i=0; i<3; i++) { - final float origin_i = origin.get(i); - final float dir_i = dir.get(i); - final float low_i = low.get(i); - final float high_i = high.get(i); - if(origin_i < low_i) { - result.set(i, low_i); - inside = false; - - // Calculate T distances to candidate planes - if( 0 != Float.floatToIntBits(dir_i) ) { - maxT[i] = (low_i - origin_i) / dir_i; - } - } else if(origin_i > high_i) { - result.set(i, high_i); - inside = false; - - // Calculate T distances to candidate planes - if( 0 != Float.floatToIntBits(dir_i) ) { - maxT[i] = (high_i - origin_i) / dir_i; - } - } - } - - // Ray origin inside bounding box - if(inside) { - result.set(origin); - return result; - } - - // Get largest of the maxT's for final choice of intersection - int whichPlane = 0; - if(maxT[1] > maxT[whichPlane]) { whichPlane = 1; } - if(maxT[2] > maxT[whichPlane]) { whichPlane = 2; } - - if( !assumeIntersection ) { - // Check final candidate actually inside box - if( 0 != ( Float.floatToIntBits(maxT[whichPlane]) & 0x80000000 ) ) { - return null; - } - - /** Use unrolled version below .. - for(int i=0; i<3; i++) { - if( i!=whichPlane ) { - result[i] = origin[i] + maxT[whichPlane] * dir[i]; - if(result[i] < minB[i] - epsilon || result[i] > maxB[i] + epsilon) { return null; } - // if(result[i] < minB[i] || result[i] > maxB[i] ) { return null; } - } - } */ - switch( whichPlane ) { - case 0: - result.setY( origin.y() + maxT[whichPlane] * dir.y() ); - if(result.y() < low.y() - epsilon || result.y() > high.y() + epsilon) { return null; } - result.setZ( origin.z() + maxT[whichPlane] * dir.z() ); - if(result.z() < low.z() - epsilon || result.z() > high.z() + epsilon) { return null; } - break; - case 1: - result.setX( origin.x() + maxT[whichPlane] * dir.x() ); - if(result.x() < low.x() - epsilon || result.x() > high.x() + epsilon) { return null; } - result.setZ( origin.z() + maxT[whichPlane] * dir.z() ); - if(result.z() < low.z() - epsilon || result.z() > high.z() + epsilon) { return null; } - break; - case 2: - result.setX( origin.x() + maxT[whichPlane] * dir.x() ); - if(result.x() < low.x() - epsilon || result.x() > high.x() + epsilon) { return null; } - result.setY( origin.y() + maxT[whichPlane] * dir.y() ); - if(result.y() < low.y() - epsilon || result.y() > high.y() + epsilon) { return null; } - break; - default: - throw new InternalError("XXX"); - } - } else { - switch( whichPlane ) { - case 0: - result.setY( origin.y() + maxT[whichPlane] * dir.y() ); - result.setZ( origin.z() + maxT[whichPlane] * dir.z() ); - break; - case 1: - result.setX( origin.x() + maxT[whichPlane] * dir.x() ); - result.setZ( origin.z() + maxT[whichPlane] * dir.z() ); - break; - case 2: - result.setX( origin.x() + maxT[whichPlane] * dir.x() ); - result.setY( origin.y() + maxT[whichPlane] * dir.y() ); - break; - default: - throw new InternalError("XXX"); - } - } - return result; // ray hits box - } - - /** - * Get the size of this AABBox where the size is represented by the - * length of the vector between low and high. - * @return a float representing the size of the AABBox - */ - public final float getSize() { - return low.dist(high); - } - - /** - * Get the Center of this AABBox - * @return the xyz-coordinates of the center of the AABBox - */ - public final Vec3f getCenter() { - return center; - } - - /** - * Scale this AABBox by a constant around fixed center - * <p> - * high and low is recomputed by scaling its distance to fixed center. - * </p> - * @param size a constant float value - * @return this AABBox for chaining - * @see #scale2(float, float[]) - */ - public final AABBox scale(final float size) { - final Vec3f tmp = new Vec3f(); - tmp.set(high).sub(center).scale(size); - high.set(center).add(tmp); - - tmp.set(low).sub(center).scale(size); - low.set(center).add(tmp); - - return this; - } - - /** - * Scale this AABBox by a constant, recomputing center - * <p> - * high and low is scaled and center recomputed. - * </p> - * @param size a constant float value - * @return this AABBox for chaining - * @see #scale(float, float[]) - */ - public final AABBox scale2(final float size) { - high.scale(size); - low.scale(size); - computeCenter(); - return this; - } - - /** - * Translate this AABBox by a float[3] vector - * @param dx the translation x-component - * @param dy the translation y-component - * @param dz the translation z-component - * @param t the float[3] translation vector - * @return this AABBox for chaining - */ - public final AABBox translate(final float dx, final float dy, final float dz) { - low.add(dx, dy, dz); - high.add(dx, dy, dz); - computeCenter(); - return this; - } - - /** - * Translate this AABBox by a float[3] vector - * @param t the float[3] translation vector - * @return this AABBox for chaining - */ - public final AABBox translate(final Vec3f t) { - low.add(t); - high.add(t); - computeCenter(); - return this; - } - - /** - * Rotate this AABBox by a float[3] vector - * @param quat the {@link Quaternion} used for rotation - * @return this AABBox for chaining - */ - public final AABBox rotate(final Quaternion quat) { - quat.rotateVector(low, low); - quat.rotateVector(high, high); - computeCenter(); - return this; - } - - public final float getMinX() { - return low.x(); - } - - public final float getMinY() { - return low.y(); - } - - public final float getMinZ() { - return low.z(); - } - - public final float getMaxX() { - return high.x(); - } - - public final float getMaxY() { - return high.y(); - } - - public final float getMaxZ() { - return high.z(); - } - - public final float getWidth(){ - return high.x() - low.x(); - } - - public final float getHeight() { - return high.y() - low.y(); - } - - public final float getDepth() { - return high.z() - low.z(); - } - - /** Returns the volume, i.e. width * height * depth */ - public final float getVolume() { - return getWidth() * getHeight() * getDepth(); - } - - /** Return true if {@link #getVolume()} is {@link FloatUtil#isZero(float)}, considering epsilon. */ - public final boolean hasZeroVolume() { - return FloatUtil.isZero(getVolume()); - } - - /** Returns the assumed 2D area, i.e. width * height while assuming low and high lies on same plane. */ - public final float get2DArea() { - return getWidth() * getHeight(); - } - - /** Return true if {@link #get2DArea()} is {@link FloatUtil#isZero(float)}, considering epsilon. */ - public final boolean hasZero2DArea() { - return FloatUtil.isZero(get2DArea()); - } - - @Override - public final boolean equals(final Object obj) { - if( obj == this ) { - return true; - } - if( null == obj || !(obj instanceof AABBox) ) { - return false; - } - final AABBox other = (AABBox) obj; - return low.isEqual(other.low) && high.isEqual(other.high); - } - @Override - public final int hashCode() { - throw new InternalError("hashCode not designed"); - } - - /** - * Transform this box using the given {@link Matrix4f} into {@code out} - * @param mat transformation {@link Matrix4f} - * @param out the resulting {@link AABBox} - * @return the resulting {@link AABBox} for chaining - */ - public AABBox transform(final Matrix4f mat, final AABBox out) { - final Vec3f tmp = new Vec3f(); - out.reset(); - out.resize( mat.mulVec3f(low, tmp) ); - out.resize( mat.mulVec3f(high, tmp) ); - out.computeCenter(); - return out; - } - - /** - * Transform this box using the {@link PMVMatrix#getMvMat() modelview} of the given {@link PMVMatrix} into {@code out} - * @param pmv transformation {@link PMVMatrix} - * @param out the resulting {@link AABBox} - * @return the resulting {@link AABBox} for chaining - */ - public AABBox transformMv(final PMVMatrix pmv, final AABBox out) { - final Vec3f tmp = new Vec3f(); - out.reset(); - out.resize( pmv.mulMvMatVec3f(low, tmp) ); - out.resize( pmv.mulMvMatVec3f(high, tmp) ); - out.computeCenter(); - return out; - } - - /** - * Assume this bounding box as being in object space and - * compute the window bounding box. - * <p> - * If <code>useCenterZ</code> is <code>true</code>, - * only 4 {@link FloatUtil#mapObjToWin(float, float, float, float[], int[], float[], float[], float[]) mapObjToWinCoords} - * operations are made on points [1..4] using {@link #getCenter()}'s z-value. - * Otherwise 8 {@link FloatUtil#mapObjToWin(float, float, float, float[], int[], float[], float[], float[]) mapObjToWinCoords} - * operation on all 8 points are performed. - * </p> - * <pre> - * .z() ------ [4] - * | | - * | | - * .y() ------ [3] - * </pre> - * @param mat4PMv [projection] x [modelview] matrix, i.e. P x Mv - * @param viewport viewport rectangle - * @param useCenterZ - * @param vec3Tmp0 3 component vector for temp storage - * @param vec4Tmp1 4 component vector for temp storage - * @param vec4Tmp2 4 component vector for temp storage - * @return - */ - public AABBox mapToWindow(final AABBox result, final Matrix4f mat4PMv, final Recti viewport, final boolean useCenterZ) { - final Vec3f tmp = new Vec3f(); - final Vec3f winPos = new Vec3f(); - { - final float objZ = useCenterZ ? center.z() : getMinZ(); - result.reset(); - - Matrix4f.mapObjToWin(tmp.set(getMinX(), getMinY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - - Matrix4f.mapObjToWin(tmp.set(getMinX(), getMaxY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - - Matrix4f.mapObjToWin(tmp.set(getMaxX(), getMaxY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - - Matrix4f.mapObjToWin(tmp.set(getMaxX(), getMinY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - } - - if( !useCenterZ ) { - final float objZ = getMaxZ(); - - Matrix4f.mapObjToWin(tmp.set(getMinX(), getMinY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - - Matrix4f.mapObjToWin(tmp.set(getMinX(), getMaxY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - - Matrix4f.mapObjToWin(tmp.set(getMaxX(), getMaxY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - - Matrix4f.mapObjToWin(tmp.set(getMaxX(), getMinY(), objZ), mat4PMv, viewport, winPos); - result.resize(winPos); - } - if( DEBUG ) { - System.err.printf("AABBox.mapToWindow: view[%s], this %s -> %s%n", viewport, toString(), result.toString()); - } - return result; - } - - @Override - public final String toString() { - return "[dim "+getWidth()+" x "+getHeight()+" x "+getDepth()+ - ", box "+low+" .. "+high+", ctr "+center+"]"; - } -} |