refactor AABB intersection
This commit is contained in:
parent
9b617a82a8
commit
1d48a49987
@ -316,7 +316,7 @@ public class Examples {
|
||||
var x1 = x0 + w;
|
||||
var y1 = random.nextInt(1, 101);
|
||||
var z1 = z0 + w;
|
||||
boxes.add(new Box(new Vec3(x0, y0, z0), new Vec3(x1, y1, z1), ground));
|
||||
boxes.add(Hittables.box(new Vec3(x0, y0, z0), new Vec3(x1, y1, z1), ground));
|
||||
}
|
||||
}
|
||||
objects.add(new HittableBinaryTree(boxes));
|
||||
|
@ -2,6 +2,7 @@ package eu.jonahbauer.raytracing.math;
|
||||
|
||||
import eu.jonahbauer.raytracing.scene.Hittable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@ -11,7 +12,6 @@ import java.util.Optional;
|
||||
* An axis-aligned bounding box.
|
||||
*/
|
||||
public record AABB(@NotNull Vec3 min, @NotNull Vec3 max) {
|
||||
public static final AABB UNIVERSE = new AABB(Vec3.MIN, Vec3.MAX);
|
||||
public static final AABB EMPTY = new AABB(Vec3.ZERO, Vec3.ZERO);
|
||||
public static final Comparator<AABB> X_AXIS = Comparator.comparing(AABB::min, Comparator.comparingDouble(Vec3::x));
|
||||
public static final Comparator<AABB> Y_AXIS = Comparator.comparing(AABB::min, Comparator.comparingDouble(Vec3::y));
|
||||
@ -57,17 +57,13 @@ public record AABB(@NotNull Vec3 min, @NotNull Vec3 max) {
|
||||
}
|
||||
|
||||
public boolean hit(@NotNull Ray ray) {
|
||||
return intersect(ray).isPresent();
|
||||
return intersect(ray) != null;
|
||||
}
|
||||
|
||||
public @NotNull Optional<Range> intersect(@NotNull Ray ray) {
|
||||
if (this == UNIVERSE) return Optional.of(Range.UNIVERSE);
|
||||
if (this == EMPTY) return Optional.empty();
|
||||
|
||||
int vmask = ray.vmask();
|
||||
|
||||
public @Nullable Range intersect(@NotNull Ray ray) {
|
||||
var origin = ray.origin();
|
||||
var invDirection = ray.direction().inv();
|
||||
var direction = ray.direction();
|
||||
var invDirection = direction.inv();
|
||||
|
||||
// calculate t values for intersection points of ray with planes through min
|
||||
var tmin = intersect(min(), origin, invDirection);
|
||||
@ -78,19 +74,27 @@ public record AABB(@NotNull Vec3 min, @NotNull Vec3 max) {
|
||||
double tlmax = Double.NEGATIVE_INFINITY; // lower limit maximum
|
||||
double tumin = Double.POSITIVE_INFINITY; // upper limit minimum
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// classify t values as lower or upper limit based on vmask
|
||||
if ((vmask & (1 << i)) == 0) {
|
||||
// classify t values as lower or upper limit based on ray direction
|
||||
if (direction.get(i) >= 0) {
|
||||
// min is lower limit and max is upper limit
|
||||
tlmax = Math.max(tlmax, tmin[i]);
|
||||
tumin = Math.min(tumin, tmax[i]);
|
||||
if (tmin[i] > tlmax) {
|
||||
tlmax = tmin[i];
|
||||
}
|
||||
if (tmax[i] < tumin) {
|
||||
tumin = tmax[i];
|
||||
}
|
||||
} else {
|
||||
// max is lower limit and min is upper limit
|
||||
tlmax = Math.max(tlmax, tmax[i]);
|
||||
tumin = Math.min(tumin, tmin[i]);
|
||||
if (tmax[i] > tlmax) {
|
||||
tlmax = tmax[i];
|
||||
}
|
||||
if (tmin[i] < tumin) {
|
||||
tumin = tmin[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tlmax < tumin ? Optional.of(new Range(tlmax, tumin)) : Optional.empty();
|
||||
return tlmax < tumin ? new Range(tlmax, tumin) : null;
|
||||
}
|
||||
|
||||
public static double @NotNull[] intersect(@NotNull Vec3 corner, @NotNull Ray ray) {
|
||||
|
@ -146,6 +146,15 @@ public record Vec3(double x, double y, double z) {
|
||||
return div(length());
|
||||
}
|
||||
|
||||
public double get(int axis) {
|
||||
return switch (axis) {
|
||||
case 0 -> x;
|
||||
case 1 -> y;
|
||||
case 2 -> z;
|
||||
default -> throw new IndexOutOfBoundsException(axis);
|
||||
};
|
||||
}
|
||||
|
||||
public @NotNull Vec3 withX(double x) {
|
||||
return new Vec3(x, y, z);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user