28package com.jogamp.math.geom;
30import com.jogamp.math.FloatUtil;
31import com.jogamp.math.Matrix4f;
32import com.jogamp.math.Quaternion;
33import com.jogamp.math.Ray;
34import com.jogamp.math.Recti;
35import com.jogamp.math.Vec3f;
36import com.jogamp.math.geom.plane.AffineTransform;
93 public AABBox(
final float lx,
final float ly,
final float lz,
94 final float hx,
final float hy,
final float hz) {
95 setSize(lx, ly, lz, hx, hy, hz);
103 public AABBox(
final float[] low,
final float[] high) {
124 setLow(Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE);
125 setHigh(-1*Float.MAX_VALUE,-1*Float.MAX_VALUE,-1*Float.MAX_VALUE);
126 center.
set( 0f, 0f, 0f);
135 private final void setHigh(
final float hx,
final float hy,
final float hz) {
136 this.hi.
set(hx, hy, hz);
144 private final void setLow(
final float lx,
final float ly,
final float lz) {
145 this.lo.
set(lx, ly, lz);
148 private final void computeCenter() {
161 center.
set(src.center);
174 return setSize(low[0],low[1],low[2], high[0],high[1],high[2]);
190 final float hx,
final float hy,
final float hz) {
191 this.lo.
set(lx, ly, lz);
192 this.hi.
set(hx, hy, hz);
221 lo.
setX( lo.x() - deltaLeft );
225 hi.
setX( hi.x() + deltaRight );
243 lo.
setY( lo.y() - deltaBottom );
247 hi.
setY( hi.y() + deltaTop );
265 this.center.
set(o.center);
279 if (newBL.x() < lo.x()) {
280 lo.
setX( newBL.x() );
282 if (newBL.y() < lo.y()) {
283 lo.
setY( newBL.y() );
285 if (newBL.z() < lo.z()) {
286 lo.
setZ( newBL.z() );
290 if (newTR.x() > hi.x()) {
291 hi.
setX( newTR.x() );
293 if (newTR.y() > hi.y()) {
294 hi.
setY( newTR.y() );
296 if (newTR.z() > hi.z()) {
297 hi.
setZ( newTR.z() );
314 if (newBL.x() < lo.x())
315 lo.
setX( newBL.x() );
316 if (newBL.y() < lo.y())
317 lo.
setY( newBL.y() );
318 if (newBL.z() < lo.z())
319 lo.
setZ( newBL.z() );
325 if (newTR.x() > hi.x())
326 hi.
setX( newTR.x() );
327 if (newTR.y() > hi.y())
328 hi.
setY( newTR.y() );
329 if (newTR.z() > hi.z())
330 hi.
setZ( newTR.z() );
345 public final AABBox resize(
final float x,
final float y,
final float z) {
380 return resize(xyz[0+offset], xyz[1+offset], xyz[2+offset]);
390 return resize(xyz[0], xyz[1], xyz[2]);
400 return resize(xyz.x(), xyz.y(), xyz.z());
408 public final boolean contains(
final float x,
final float y) {
409 return lo.x()<=x && x<=hi.x() &&
410 lo.y()<=y && y<=hi.y();
419 public final boolean contains(
final float x,
final float y,
final float z) {
420 return lo.x()<=x && x<=hi.x() &&
421 lo.y()<=y && y<=hi.y() &&
422 lo.z()<=z && z<=hi.z();
438 return Math.max(lo.x(), o.lo.x()) <= Math.min(hi.x(), o.hi.x()) &&
439 Math.max(lo.y(), o.lo.y()) <= Math.min(hi.y(), o.hi.y()) &&
440 Math.max(lo.z(), o.lo.z()) <= Math.min(hi.z(), o.hi.z());
445 return hi.x() >= o.hi.x() &&
446 hi.y() >= o.hi.y() &&
447 hi.z() >= o.hi.z() &&
448 lo.x() <= o.lo.x() &&
449 lo.y() <= o.lo.y() &&
462 public final boolean intersects2DRegion(
final float x,
final float y,
final float w,
final float h) {
463 if (w <= 0 || h <= 0) {
469 if (_w <= 0 || _h <= 0) {
499 final float dirX = ray.
dir.x();
500 final float diffX = ray.
orig.x() - center.x();
501 final float extX = hi.x() - center.x();
502 if( Math.abs(diffX) > extX && diffX*dirX >= 0f )
return false;
504 final float dirY = ray.
dir.y();
505 final float diffY = ray.
orig.y() - center.y();
506 final float extY = hi.y() - center.y();
507 if( Math.abs(diffY) > extY && diffY*dirY >= 0f )
return false;
509 final float dirZ = ray.
dir.z();
510 final float diffZ = ray.
orig.z() - center.z();
511 final float extZ = hi.z() - center.z();
512 if( Math.abs(diffZ) > extZ && diffZ*dirZ >= 0f )
return false;
514 final float absDirY = Math.abs(dirY);
515 final float absDirZ = Math.abs(dirZ);
517 float f = dirY * diffZ - dirZ * diffY;
518 if( Math.abs(f) > extY*absDirZ + extZ*absDirY )
return false;
520 final float absDirX = Math.abs(dirX);
522 f = dirZ * diffX - dirX * diffZ;
523 if( Math.abs(f) > extX*absDirZ + extZ*absDirX )
return false;
525 f = dirX * diffY - dirY * diffX;
526 if( Math.abs(f) > extX*absDirY + extY*absDirX )
return false;
564 final boolean assumeIntersection) {
565 final float[] maxT = { -1f, -1f, -1f };
570 boolean inside =
true;
602 if(origin.x() < lo.x()) {
607 if( 0 != Float.floatToIntBits(dir.x()) ) {
608 maxT[0] = (lo.x() - origin.x()) / dir.x();
610 }
else if(origin.x() > hi.x()) {
615 if( 0 != Float.floatToIntBits(dir.x()) ) {
616 maxT[0] = (hi.x() - origin.x()) / dir.x();
621 if(origin.y() < lo.y()) {
626 if( 0 != Float.floatToIntBits(dir.y()) ) {
627 maxT[1] = (lo.y() - origin.y()) / dir.y();
629 }
else if(origin.y() > hi.y()) {
634 if( 0 != Float.floatToIntBits(dir.y()) ) {
635 maxT[1] = (hi.y() - origin.y()) / dir.y();
640 if(origin.z() < lo.z()) {
645 if( 0 != Float.floatToIntBits(dir.z()) ) {
646 maxT[2] = (lo.z() - origin.z()) / dir.z();
648 }
else if(origin.z() > hi.z()) {
653 if( 0 != Float.floatToIntBits(dir.z()) ) {
654 maxT[2] = (hi.z() - origin.z()) / dir.z();
667 if(maxT[1] > maxT[whichPlane]) { whichPlane = 1; }
668 if(maxT[2] > maxT[whichPlane]) { whichPlane = 2; }
670 if( !assumeIntersection ) {
672 if( 0 != ( Float.floatToIntBits(maxT[whichPlane]) & FloatUtil.IEC559_SIGN_BIT ) ) {
684 switch( whichPlane ) {
686 result.
setY( origin.y() + maxT[whichPlane] * dir.y() );
687 if(result.y() < lo.y() - epsilon || result.y() > hi.y() + epsilon) {
return null; }
688 result.
setZ( origin.z() + maxT[whichPlane] * dir.z() );
689 if(result.z() < lo.z() - epsilon || result.z() > hi.z() + epsilon) {
return null; }
692 result.
setX( origin.x() + maxT[whichPlane] * dir.x() );
693 if(result.x() < lo.x() - epsilon || result.x() > hi.x() + epsilon) {
return null; }
694 result.
setZ( origin.z() + maxT[whichPlane] * dir.z() );
695 if(result.z() < lo.z() - epsilon || result.z() > hi.z() + epsilon) {
return null; }
698 result.
setX( origin.x() + maxT[whichPlane] * dir.x() );
699 if(result.x() < lo.x() - epsilon || result.x() > hi.x() + epsilon) {
return null; }
700 result.
setY( origin.y() + maxT[whichPlane] * dir.y() );
701 if(result.y() < lo.y() - epsilon || result.y() > hi.y() + epsilon) {
return null; }
704 throw new InternalError(
"XXX");
707 switch( whichPlane ) {
709 result.
setY( origin.y() + maxT[whichPlane] * dir.y() );
710 result.
setZ( origin.z() + maxT[whichPlane] * dir.z() );
713 result.
setX( origin.x() + maxT[whichPlane] * dir.x() );
714 result.
setZ( origin.z() + maxT[whichPlane] * dir.z() );
717 result.
setX( origin.x() + maxT[whichPlane] * dir.x() );
718 result.
setY( origin.y() + maxT[whichPlane] * dir.y() );
721 throw new InternalError(
"XXX");
771 public final AABBox scale(
final float sX,
final float sY,
final float sZ) {
809 public final AABBox scale2(
final float sX,
final float sY,
final float sZ) {
880 return hi.x() - lo.x();
884 return hi.y() - lo.y();
888 return hi.z() - lo.z();
912 public final boolean equals(
final Object obj) {
916 if(
null == obj || !(obj instanceof
AABBox) ) {
924 throw new InternalError(
"hashCode not designed");
970 final float objZ = useCenterZ ? center.z() :
getMinZ();
1002 System.err.printf(
"AABBox.mapToWindow: view[%s], this %s -> %s%n", viewport,
toString(), result.
toString());
1010 ", box "+lo+
" .. "+hi+
", ctr "+center+
"]";
Basic Float math utility functions.
static boolean isZero(final float a, final float epsilon)
Returns true if value is zero, i.e.
static final boolean DEBUG
Basic 4x4 float matrix implementation using fields for intensive use-cases (host operations).
static boolean mapObjToWin(final Vec3f obj, final Matrix4f mMv, final Matrix4f mP, final Recti viewport, final Vec3f winPos)
Map object coordinates to window coordinates.
final Vec3f mulVec3f(final Vec3f v_in, final Vec3f v_out)
Affine 3f-vector transformation by 4x4 matrix.
Quaternion implementation supporting Gimbal-Lock free rotations.
final Vec3f rotateVector(final Vec3f vecIn, final Vec3f vecOut)
Simple compound denoting a ray.
final Vec3f dir
Normalized direction vector of ray.
final Vec3f orig
Origin of Ray.
Rectangle with x, y, width and height integer components.
3D Vector based upon three float components.
Vec3f mul(final float val)
Returns this * val; creates new vector.
Vec3f scale(final float s)
this = this * s, returns this.
Vec3f sub(final Vec3f b)
this = this - b, returns this.
boolean isEqual(final Vec3f o, final float epsilon)
Equals check using a given FloatUtil#EPSILON value and FloatUtil#isEqual(float, float,...
float dist(final Vec3f o)
Return the distance between this vector and the given one.
Vec3f set(final Vec3f o)
this = o, returns this.
Vec3f add(final float dx, final float dy, final float dz)
this = this + { dx, dy, dz }, returns this.
Axis Aligned Bounding Box.
final boolean contains(final float x, final float y, final float z)
Returns whether this AABBox contains given 3D point.
final AABBox resize(final float x, final float y, final float z)
Resize the AABBox to encapsulate the passed xyz-coordinates.
final AABBox scale(final float sX, final float sY, final float sZ)
Scale this AABBox by constants around fixed center.
final AABBox resize(final AABBox newBox, final AffineTransform t, final Vec3f tmpV3)
Resize the AABBox to encapsulate another AABox, which will be transformed on the fly first.
AABBox(final float lx, final float ly, final float lz, final float hx, final float hy, final float hz)
Create an AABBox specifying the coordinates of the low and high.
AABBox(final AABBox src)
Create an AABBox copying all values from the given one.
final AABBox resizeHeight(final float deltaBottom, final float deltaTop)
Resize height of this AABBox with explicit bottom- and top delta values.
final AABBox scale2(final float s)
Scale this AABBox by a constant, recomputing center.
final Vec3f getHigh()
Returns the maximum right-top-near (xyz) coordinate.
final Vec3f getLow()
Returns the minimum left-bottom-far (xyz) coordinate.
final AABBox scale2(final float sX, final float sY, final float sZ)
Scale this AABBox by constants, recomputing center.
final float get2DArea()
Returns the assumed 2D area, i.e.
final boolean contains(final float x, final float y)
Returns whether this AABBox contains given 2D point.
final boolean contains(final AABBox o)
Returns whether this AABBox fully contains given AABBox.
AABBox mapToWindow(final AABBox result, final Matrix4f mat4PMv, final Recti viewport, final boolean useCenterZ)
Assume this bounding box as being in object space and compute the window bounding box.
final AABBox translate(final float dx, final float dy, final float dz)
Translate this AABBox by a float[3] vector.
final AABBox setSize(final float lx, final float ly, final float lz, final float hx, final float hy, final float hz)
Set size of the AABBox specifying the coordinates of the low and high.
AABBox()
Create an Axis Aligned bounding box (AABBox) with the inverse low/high, allowing the next resize(floa...
final AABBox resize(final float[] xyz)
Resize the AABBox to encapsulate the passed xyz-coordinates.
AABBox(final float[] low, final float[] high)
Create a AABBox defining the low and high.
final boolean equals(final Object obj)
final AABBox reset()
Resets this box to the inverse low/high, allowing the next resize(float, float, float) command to hit...
final boolean hasZero2DArea()
Return true if get2DArea() is FloatUtil#isZero(float), considering epsilon.
final boolean intersects(final AABBox o)
Returns whether this AABBox intersects (partially contains) given AABBox.
final AABBox setSize(final float[] low, final float[] high)
Set size of the AABBox specifying the coordinates of the low and high.
final float getSize()
Get the size of this AABBox where the size is represented by the length of the vector between low and...
final float getVolume()
Returns the volume, i.e.
AABBox(final Vec3f low, final Vec3f high)
Create a AABBox defining the low and high.
final boolean intersectsRay(final Ray ray)
Check if Ray intersects this bounding box.
final AABBox setSize(final Vec3f low, final Vec3f high)
Set size of the AABBox specifying the coordinates of the low and high.
AABBox transform(final Matrix4f mat, final AABBox out)
Transform this box using the given Matrix4f into out @endiliteral.
final AABBox scale(final float s)
Scale this AABBox by a constant around fixed center.
final AABBox copy(final AABBox src)
Copy given AABBox 'src' values to this AABBox.
final AABBox resize(final AABBox newBox)
Resize the AABBox to encapsulate another AABox.
final boolean hasZeroVolume()
Return true if getVolume() is FloatUtil#isZero(float), considering epsilon.
final AABBox translate(final Vec3f t)
Translate this AABBox by a float[3] vector.
final AABBox resize(final Vec3f xyz)
Resize the AABBox to encapsulate the passed xyz-coordinates.
final AABBox resize(final float[] xyz, final int offset)
Resize the AABBox to encapsulate the passed xyz-coordinates.
final Vec3f getRayIntersection(final Vec3f result, final Ray ray, final float epsilon, final boolean assumeIntersection)
Return intersection of a Ray with this bounding box, or null if none exist.
final AABBox rotate(final Quaternion quat)
Rotate this AABBox by a float[3] vector.
final AABBox resizeWidth(final float deltaLeft, final float deltaRight)
Resize width of this AABBox with explicit left- and right delta values.
final boolean intersects2DRegion(final float x, final float y, final float w, final float h)
Check if there is a common region between this AABBox and the passed 2D region irrespective of z rang...
final Vec3f getCenter()
Returns computed center of this AABBox of getLow() and getHigh().