@Override // from IBox public boolean intersection(IRay3 ray, Vector3 result) { IVector3 origin = ray.origin(); if (contains(origin)) { result.set(origin); return true; } IVector3 dir = ray.direction(); double t = Float.MAX_VALUE; if (Math.abs(dir.x()) > MathUtil.EPSILON) { t = Math.min(t, intersectionX(ray, _minExtent.x)); t = Math.min(t, intersectionX(ray, _maxExtent.x)); } if (Math.abs(dir.y()) > MathUtil.EPSILON) { t = Math.min(t, intersectionY(ray, _minExtent.y)); t = Math.min(t, intersectionY(ray, _maxExtent.y)); } if (Math.abs(dir.z()) > MathUtil.EPSILON) { t = Math.min(t, intersectionZ(ray, _minExtent.z)); t = Math.min(t, intersectionZ(ray, _maxExtent.z)); } if (t == Float.MAX_VALUE) { return false; } origin.addScaled(dir, t, result); return true; }
/** * Helper method for {@link #intersects(Ray3)}. Determines whether the ray intersects the box at * the plane where z equals the value specified. */ protected boolean intersectsZ(IRay3 ray, double z) { IVector3 origin = ray.origin(), dir = ray.direction(); double t = (z - origin.z()) / dir.z(); if (t < 0f) { return false; } double ix = origin.x() + t * dir.x(), iy = origin.y() + t * dir.y(); return ix >= _minExtent.x && ix <= _maxExtent.x && iy >= _minExtent.y && iy <= _maxExtent.y; }
/** * Helper method for {@link #intersects(Ray3)}. Determines whether the ray intersects the box at * the plane where y equals the value specified. */ protected boolean intersectsY(IRay3 ray, double y) { IVector3 origin = ray.origin(), dir = ray.direction(); double t = (y - origin.y()) / dir.y(); if (t < 0f) { return false; } double ix = origin.x() + t * dir.x(), iz = origin.z() + t * dir.z(); return ix >= _minExtent.x && ix <= _maxExtent.x && iz >= _minExtent.z && iz <= _maxExtent.z; }
/** * Helper method for {@link #intersects(Ray3)}. Determines whether the ray intersects the box at * the plane where x equals the value specified. */ protected boolean intersectsX(IRay3 ray, double x) { IVector3 origin = ray.origin(), dir = ray.direction(); double t = (x - origin.x()) / dir.x(); if (t < 0f) { return false; } double iy = origin.y() + t * dir.y(), iz = origin.z() + t * dir.z(); return iy >= _minExtent.y && iy <= _maxExtent.y && iz >= _minExtent.z && iz <= _maxExtent.z; }
@Override // from IBox public boolean intersects(IRay3 ray) { IVector3 dir = ray.direction(); return Math.abs(dir.x()) > MathUtil.EPSILON && (intersectsX(ray, _minExtent.x) || intersectsX(ray, _maxExtent.x)) || Math.abs(dir.y()) > MathUtil.EPSILON && (intersectsY(ray, _minExtent.y) || intersectsY(ray, _maxExtent.y)) || Math.abs(dir.z()) > MathUtil.EPSILON && (intersectsZ(ray, _minExtent.z) || intersectsZ(ray, _maxExtent.z)); }
/** * Helper method for {@link #intersection}. Finds the <code>t</code> value where the ray * intersects the box at the plane where z equals the value specified, or returns {@link * Float#MAX_VALUE} if there is no such intersection. */ protected double intersectionZ(IRay3 ray, double z) { IVector3 origin = ray.origin(), dir = ray.direction(); double t = (z - origin.z()) / dir.z(); if (t < 0f) { return Float.MAX_VALUE; } double ix = origin.x() + t * dir.x(), iy = origin.y() + t * dir.y(); return (ix >= _minExtent.x && ix <= _maxExtent.x && iy >= _minExtent.y && iy <= _maxExtent.y) ? t : Float.MAX_VALUE; }
/** * Helper method for {@link #intersection}. Finds the <code>t</code> value where the ray * intersects the box at the plane where y equals the value specified, or returns {@link * Float#MAX_VALUE} if there is no such intersection. */ protected double intersectionY(IRay3 ray, double y) { IVector3 origin = ray.origin(), dir = ray.direction(); double t = (y - origin.y()) / dir.y(); if (t < 0f) { return Float.MAX_VALUE; } double ix = origin.x() + t * dir.x(), iz = origin.z() + t * dir.z(); return (ix >= _minExtent.x && ix <= _maxExtent.x && iz >= _minExtent.z && iz <= _maxExtent.z) ? t : Float.MAX_VALUE; }