Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:13:46

0001 #ifndef BVH_V2_RAY_H
0002 #define BVH_V2_RAY_H
0003 
0004 #include "bvh/v2/vec.h"
0005 
0006 namespace bvh::v2 {
0007 
0008 struct Octant {
0009     uint32_t value = 0;
0010     static constexpr size_t max_dim = sizeof(value) * CHAR_BIT;
0011 
0012     uint32_t operator [] (size_t i) const { return (value >> i) & uint32_t{1}; }
0013 };
0014 
0015 template <typename T, size_t N>
0016 struct Ray {
0017     Vec<T, N> org, dir;
0018     T tmin, tmax;
0019 
0020     Ray() = default;
0021     BVH_ALWAYS_INLINE Ray(
0022         const Vec<T, N>& org,
0023         const Vec<T, N>& dir,
0024         T tmin = 0,
0025         T tmax = std::numeric_limits<T>::max())
0026         : org(org), dir(dir), tmin(tmin), tmax(tmax)
0027     {}
0028 
0029     template <bool SafeInverse = false>
0030     BVH_ALWAYS_INLINE Vec<T, N> get_inv_dir() const {
0031         return Vec<T, N>::generate([&] (size_t i) {
0032             return SafeInverse ? safe_inverse(dir[i]) : static_cast<T>(1) / dir[i];
0033         });
0034     }
0035 
0036     BVH_ALWAYS_INLINE Octant get_octant() const {
0037         static_assert(N <= Octant::max_dim);
0038         Octant octant;
0039         static_for<0, N>([&] (size_t i) {
0040             octant.value |= std::signbit(dir[i]) * (uint32_t{1} << i);
0041         });
0042         return octant;
0043     }
0044 
0045     // Pads the inverse direction according to T. Ize's "Robust BVH ray traversal"
0046     BVH_ALWAYS_INLINE static Vec<T, N> pad_inv_dir(const Vec<T, N>& inv_dir) {
0047         return Vec<T, N>::generate([&] (size_t i) { return add_ulp_magnitude(inv_dir[i], 2); });
0048     }
0049 };
0050 
0051 } // namespace bvh::v2
0052 
0053 #endif