Skip to content

Commit 9c68ba7

Browse files
committed
Fix
1 parent f430832 commit 9c68ba7

File tree

1 file changed

+69
-29
lines changed

1 file changed

+69
-29
lines changed

src/main/java/math/Bounds.java

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,24 @@ public Vector3f closestPoint(Vector3f point) {
6666
* considered inside if all of its coordinates are between the minimum and
6767
* maximum coordinates of the box.
6868
*
69-
* @param point the point to check
69+
* @param p the point to check
7070
* @return {@code true} if the point is inside the bounding box, {@code false}
7171
* otherwise
7272
*/
73-
public boolean contains(Vector3f point) {
74-
return point.x >= min.x && point.x <= max.x && point.y >= min.y
75-
&& point.y <= max.y && point.z >= min.z && point.z <= max.z;
73+
public boolean contains(Vector3f p) {
74+
return p.x >= min.x && p.x <= max.x && p.y >= min.y
75+
&& p.y <= max.y && p.z >= min.z && p.z <= max.z;
7676
}
7777

7878
/**
7979
* Expands the bounding box to encompass the given {@code point}. If the point
8080
* is outside the current bounds, the box will be enlarged to include it.
8181
*
82-
* @param point the point to include in the bounding box
82+
* @param p the point to include in the bounding box
8383
*/
84-
public void encapsulate(Vector3f point) {
85-
min = new Vector3f(Math.min(min.x, point.x), Math.min(min.y, point.y),
86-
Math.min(min.z, point.z));
87-
max = new Vector3f(Math.max(max.x, point.x), Math.max(max.y, point.y),
88-
Math.max(max.z, point.z));
84+
public void encapsulate(Vector3f p) {
85+
min.set(Math.min(min.x, p.x), Math.min(min.y, p.y), Math.min(min.z, p.z));
86+
max.set(Math.max(max.x, p.x), Math.max(max.y, p.y), Math.max(max.z, p.z));
8987
}
9088

9189
/**
@@ -96,34 +94,72 @@ public void encapsulate(Vector3f point) {
9694
* @param amount the amount to expand the bounding box by
9795
*/
9896
public void expand(float amount) {
99-
Vector3f expansion = new Vector3f(amount / 2, amount / 2, amount / 2);
100-
min = min.subtract(expansion);
101-
max = max.add(expansion);
97+
float halfAmount = amount / 2;
98+
min.subtractLocal(halfAmount, halfAmount, halfAmount);
99+
max.addLocal(halfAmount, halfAmount, halfAmount);
102100
}
103101

104102
/**
105-
* Tests if the given {@code ray} intersects the bounding box. The
106-
* intersection is checked using the slab method, which determines if the ray
107-
* intersects the box along each axis.
103+
* Tests whether the given ray intersects this axis-aligned bounding box
104+
* (AABB).
105+
* <p>
106+
* The method uses the slab method to compute the intersection by checking the
107+
* ray's position and direction relative to the box's bounds in each axis (x,
108+
* y, z). It accounts for parallel rays and updates intersection intervals to
109+
* determine if there is an overlap.
110+
* </p>
108111
*
109-
* @param ray the ray to test for intersection
110-
* @return {@code true} if the ray intersects the bounding box, {@code false}
111-
* otherwise
112+
* @param ray the {@link Ray3f} to test for intersection with this AABB. The
113+
* ray must have its inverse direction precomputed and accessible
114+
* via {@code ray.getDirectionInv()} for optimal performance.
115+
* @return {@code true} if the ray intersects the AABB, {@code false}
116+
* otherwise.
112117
*/
113118
public boolean intersectRay(Ray3f ray) {
114-
Vector3f invDir = ray.getDirection().reciprocal();
115-
Vector3f tMin = min.subtract(ray.getOrigin()).mult(invDir);
116-
Vector3f tMax = max.subtract(ray.getOrigin()).mult(invDir);
119+
if (ray.getDirection().isZero()) {
120+
return false; // A ray with zero direction cannot intersect anything
121+
}
117122

118-
float t1 = Math.min(tMin.x, tMax.x);
119-
float t2 = Math.max(tMin.x, tMax.x);
123+
if (min.equals(max)) {
124+
return ray.getOrigin().equals(min);
125+
}
120126

121-
for (int i = 1; i < 3; i++) { // For y and z axes
122-
t1 = Math.max(t1, Math.min(tMin.get(i), tMax.get(i)));
123-
t2 = Math.min(t2, Math.max(tMin.get(i), tMax.get(i)));
127+
float tmin = 0.0f;
128+
float tmax = Float.POSITIVE_INFINITY;
129+
130+
for (int d = 0; d < 3; ++d) {
131+
float invDir = ray.getDirectionInv().get(d);
132+
133+
// Handle zero direction component
134+
if (invDir == 0.0f) {
135+
if (ray.getOrigin().get(d) < min.get(d)
136+
|| ray.getOrigin().get(d) > max.get(d)) {
137+
return false;
138+
}
139+
continue;
140+
}
141+
142+
float bmin, bmax;
143+
if (invDir < 0.0f) {
144+
bmin = max.get(d);
145+
bmax = min.get(d);
146+
} else {
147+
bmin = min.get(d);
148+
bmax = max.get(d);
149+
}
150+
151+
float dmin = (bmin - ray.getOrigin().get(d)) * invDir;
152+
float dmax = (bmax - ray.getOrigin().get(d)) * invDir;
153+
154+
tmin = Math.max(tmin, dmin);
155+
tmax = Math.min(tmax, dmax);
156+
157+
if (tmin > tmax) {
158+
return false;
159+
}
124160
}
125161

126-
return t1 <= t2 && t2 >= 0;
162+
return true;
127163
}
128164

129165
/**
@@ -162,8 +198,12 @@ public float sqrDistance(Vector3f point) {
162198
*
163199
* @param min the new minimum corner
164200
* @param max the new maximum corner
201+
* @throws IllegalArgumentException if min or max is null.
165202
*/
166203
public void setMinMax(Vector3f min, Vector3f max) {
204+
if (min == null || max == null) {
205+
throw new IllegalArgumentException("Min and Max cannot be null.");
206+
}
167207
this.min = new Vector3f(min);
168208
this.max = new Vector3f(max);
169209
}
@@ -185,5 +225,5 @@ public Vector3f getMin() {
185225
public Vector3f getMax() {
186226
return max;
187227
}
188-
228+
189229
}

0 commit comments

Comments
 (0)