From 1d48a499873198fd319ed32cf8629eefd65eda32 Mon Sep 17 00:00:00 2001 From: jbb01 <32650546+jbb01@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:50:09 +0200 Subject: [PATCH] refactor AABB intersection --- .../eu/jonahbauer/raytracing/Examples.java | 2 +- .../eu/jonahbauer/raytracing/math/AABB.java | 36 ++++++++++--------- .../eu/jonahbauer/raytracing/math/Vec3.java | 9 +++++ 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/main/java/eu/jonahbauer/raytracing/Examples.java b/src/main/java/eu/jonahbauer/raytracing/Examples.java index 5f38dcb..8e55352 100644 --- a/src/main/java/eu/jonahbauer/raytracing/Examples.java +++ b/src/main/java/eu/jonahbauer/raytracing/Examples.java @@ -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)); diff --git a/src/main/java/eu/jonahbauer/raytracing/math/AABB.java b/src/main/java/eu/jonahbauer/raytracing/math/AABB.java index 44796fc..b01dd28 100644 --- a/src/main/java/eu/jonahbauer/raytracing/math/AABB.java +++ b/src/main/java/eu/jonahbauer/raytracing/math/AABB.java @@ -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 X_AXIS = Comparator.comparing(AABB::min, Comparator.comparingDouble(Vec3::x)); public static final Comparator 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 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) { diff --git a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java index 767febe..9e59a0a 100644 --- a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java +++ b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java @@ -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); }