blob: ddad406dc3994ed448217e320a7ce3647da6d483 [file] [log] [blame]
#ifndef AABB_H
#define AABB_H
//==============================================================================================
// Originally written in 2016 by Peter Shirley <ptrshrl@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy (see file COPYING.txt) of the CC0 Public
// Domain Dedication along with this software. If not, see
// <http://creativecommons.org/publicdomain/zero/1.0/>.
//
// The original source code is from
// https://github.com/RayTracing/raytracing.github.io/tree/release/src/TheNextWeek
//
// Changes to the original code follow the following license.
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//==============================================================================================
#include "rtweekend.h"
#include <algorithm>
#include <type_traits>
class aabb {
public:
interval x, y, z;
// The default AABB is empty, since intervals are empty by default.
__host__ __device__ aabb() {}
__host__ __device__ aabb(const interval &ix, const interval &iy,
const interval &iz)
: x(ix), y(iy), z(iz) {}
__host__ __device__ aabb(const point3 &a, const point3 &b) {
x = interval(fmin(a[0], b[0]), fmax(a[0], b[0]));
y = interval(fmin(a[1], b[1]), fmax(a[1], b[1]));
z = interval(fmin(a[2], b[2]), fmax(a[2], b[2]));
}
__host__ __device__ aabb(const aabb &box0, const aabb &box1) {
x = interval(box0.x, box1.x);
y = interval(box0.y, box1.y);
z = interval(box0.z, box1.z);
}
__host__ __device__ aabb pad() {
double delta = 0.0001;
interval new_x = (x.size() >= delta) ? x : x.expand(delta);
interval new_y = (y.size() >= delta) ? y : y.expand(delta);
interval new_z = (z.size() >= delta) ? z : z.expand(delta);
return aabb(new_x, new_y, new_z);
}
__host__ __device__ const interval &axis(int n) const {
if (n == 1)
return y;
if (n == 2)
return z;
return x;
}
__host__ __device__ bool hit(const ray &r, interval ray_t) const {
for (int a = 0; a < 3; a++) {
auto invD = 1 / r.direction()[a];
auto orig = r.origin()[a];
auto t0 = (axis(a).min - orig) * invD;
auto t1 = (axis(a).max - orig) * invD;
if (invD < 0)
rt_swap(t0, t1);
if (t0 > ray_t.min)
ray_t.min = t0;
if (t1 < ray_t.max)
ray_t.max = t1;
if (ray_t.max <= ray_t.min)
return false;
}
return true;
}
};
__host__ __device__ aabb operator+(const aabb &bbox, const vec3 &offset) {
return aabb(bbox.x + offset.x(), bbox.y + offset.y(), bbox.z + offset.z());
}
__host__ __device__ aabb operator+(const vec3 &offset, const aabb &bbox) {
return bbox + offset;
}
#endif