switch from octree to binary tree
parent
3a3949f518
commit
9106ccf8b0
@ -0,0 +1,67 @@
|
|||||||
|
package eu.jonahbauer.raytracing.scene.util;
|
||||||
|
|
||||||
|
import eu.jonahbauer.raytracing.math.AABB;
|
||||||
|
import eu.jonahbauer.raytracing.math.Ray;
|
||||||
|
import eu.jonahbauer.raytracing.scene.Hittable;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class HittableBinaryTree extends HittableCollection {
|
||||||
|
private final @Nullable Hittable left;
|
||||||
|
private final @Nullable Hittable right;
|
||||||
|
private final @NotNull AABB bbox;
|
||||||
|
|
||||||
|
public HittableBinaryTree(@NotNull List<? extends @NotNull Hittable> objects) {
|
||||||
|
bbox = AABB.getBoundingBox(objects).orElse(AABB.EMPTY);
|
||||||
|
if (objects.isEmpty()) {
|
||||||
|
left = null;
|
||||||
|
right = null;
|
||||||
|
} else if (objects.size() == 1) {
|
||||||
|
left = objects.getFirst();
|
||||||
|
right = null;
|
||||||
|
} else if (objects.size() == 2) {
|
||||||
|
left = objects.getFirst();
|
||||||
|
right = objects.getLast();
|
||||||
|
} else {
|
||||||
|
var x = bbox.x().size();
|
||||||
|
var y = bbox.y().size();
|
||||||
|
var z = bbox.z().size();
|
||||||
|
Comparator<AABB> comparator;
|
||||||
|
if (x > y && x > z) {
|
||||||
|
comparator = AABB.X_AXIS;
|
||||||
|
} else if (y > z) {
|
||||||
|
comparator = AABB.Y_AXIS;
|
||||||
|
} else {
|
||||||
|
comparator = AABB.Z_AXIS;
|
||||||
|
}
|
||||||
|
var sorted = objects.stream().sorted(Comparator.comparing(Hittable::getBoundingBox, comparator)).toList();
|
||||||
|
var size = sorted.size();
|
||||||
|
|
||||||
|
left = new HittableBinaryTree(sorted.subList(0, size / 2));
|
||||||
|
right = new HittableBinaryTree(sorted.subList(size / 2, size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hit(@NotNull Ray ray, @NotNull State state) {
|
||||||
|
if (!bbox.hit(ray)) return;
|
||||||
|
if (left instanceof HittableCollection coll) {
|
||||||
|
coll.hit(ray, state);
|
||||||
|
} else if (left != null) {
|
||||||
|
hit(state, ray, left);
|
||||||
|
}
|
||||||
|
if (right instanceof HittableCollection coll) {
|
||||||
|
coll.hit(ray, state);
|
||||||
|
} else if (right != null) {
|
||||||
|
hit(state, ray, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull AABB getBoundingBox() {
|
||||||
|
return bbox;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue