Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef BVH_V2_VEC_H
0002 #define BVH_V2_VEC_H
0003 
0004 #include "bvh/v2/utils.h"
0005 
0006 #include <cstddef>
0007 #include <numeric>
0008 #include <cmath>
0009 #include <algorithm>
0010 
0011 namespace bvh::v2 {
0012 
0013 template <typename T, size_t N>
0014 struct Vec {
0015     T values[N];
0016 
0017     Vec() = default;
0018     template <typename... Args>
0019     BVH_ALWAYS_INLINE Vec(T x, T y, Args&&... args) : values { x, y, static_cast<T>(std::forward<Args>(args))... } {}
0020     BVH_ALWAYS_INLINE explicit Vec(T x) { std::fill(values, values + N, x); }
0021 
0022     template <typename Compare>
0023     BVH_ALWAYS_INLINE size_t get_best_axis(Compare&& compare) const {
0024         size_t axis = 0;
0025         static_for<1, N>([&] (size_t i) { 
0026             if (compare(values[i], values[axis]))
0027                 axis = i;
0028         });
0029         return axis;
0030     }
0031 
0032     // Note: These functions are designed to be robust to NaNs
0033     BVH_ALWAYS_INLINE size_t get_largest_axis() const { return get_best_axis(std::greater<T>()); }
0034     BVH_ALWAYS_INLINE size_t get_smallest_axis() const { return get_best_axis(std::less<T>()); }
0035 
0036     BVH_ALWAYS_INLINE T& operator [] (size_t i) { return values[i]; }
0037     BVH_ALWAYS_INLINE T operator [] (size_t i) const { return values[i]; }
0038 
0039     template <typename F>
0040     BVH_ALWAYS_INLINE static Vec<T, N> generate(F&& f) {
0041         Vec<T, N> v;
0042         static_for<0, N>([&] (size_t i) { v[i] = f(i); });
0043         return v;
0044     }
0045 };
0046 
0047 template <typename T, size_t N>
0048 BVH_ALWAYS_INLINE Vec<T, N> operator + (const Vec<T, N>& a, const Vec<T, N>& b) {
0049     return Vec<T, N>::generate([&] (size_t i) { return a[i] + b[i]; });
0050 }
0051 
0052 template <typename T, size_t N>
0053 BVH_ALWAYS_INLINE Vec<T, N> operator - (const Vec<T, N>& a, const Vec<T, N>& b) {
0054     return Vec<T, N>::generate([&] (size_t i) { return a[i] - b[i]; });
0055 }
0056 
0057 template <typename T, size_t N>
0058 BVH_ALWAYS_INLINE Vec<T, N> operator - (const Vec<T, N>& a) {
0059     return Vec<T, N>::generate([&] (size_t i) { return -a[i]; });
0060 }
0061 
0062 template <typename T, size_t N>
0063 BVH_ALWAYS_INLINE Vec<T, N> operator * (const Vec<T, N>& a, const Vec<T, N>& b) {
0064     return Vec<T, N>::generate([&] (size_t i) { return a[i] * b[i]; });
0065 }
0066 
0067 template <typename T, size_t N>
0068 BVH_ALWAYS_INLINE Vec<T, N> operator / (const Vec<T, N>& a, const Vec<T, N>& b) {
0069     return Vec<T, N>::generate([&] (size_t i) { return a[i] / b[i]; });
0070 }
0071 
0072 template <typename T, size_t N>
0073 BVH_ALWAYS_INLINE Vec<T, N> operator * (const Vec<T, N>& a, T b) {
0074     return Vec<T, N>::generate([&] (size_t i) { return a[i] * b; });
0075 }
0076 
0077 template <typename T, size_t N>
0078 BVH_ALWAYS_INLINE Vec<T, N> operator * (T a, const Vec<T, N>& b) {
0079     return b * a;
0080 }
0081 
0082 template <typename T, size_t N>
0083 BVH_ALWAYS_INLINE Vec<T, N> operator / (T a, const Vec<T, N>& b) {
0084     return Vec<T, N>::generate([&] (size_t i) { return a / b[i]; });
0085 }
0086 
0087 template <typename T, size_t N>
0088 BVH_ALWAYS_INLINE Vec<T, N> robust_min(const Vec<T, N>& a, const Vec<T, N>& b) {
0089     return Vec<T, N>::generate([&] (size_t i) { return robust_min(a[i], b[i]); });
0090 }
0091 
0092 template <typename T, size_t N>
0093 BVH_ALWAYS_INLINE Vec<T, N> robust_max(const Vec<T, N>& a, const Vec<T, N>& b) {
0094     return Vec<T, N>::generate([&] (size_t i) { return robust_max(a[i], b[i]); });
0095 }
0096 
0097 template <typename T, size_t N>
0098 BVH_ALWAYS_INLINE T dot(const Vec<T, N>& a, const Vec<T, N>& b) {
0099     // return std::transform_reduce(a.values, a.values + N, b.values, T(0));
0100     return std::inner_product(a.values, a.values + N, b.values, T(0));
0101 }
0102 
0103 template <typename T>
0104 BVH_ALWAYS_INLINE Vec<T, 3> cross(const Vec<T, 3>& a, const Vec<T, 3>& b) {
0105     return Vec<T, 3>(
0106         a[1] * b[2] - a[2] * b[1],
0107         a[2] * b[0] - a[0] * b[2],
0108         a[0] * b[1] - a[1] * b[0]);
0109 }
0110 
0111 template <typename T, size_t N>
0112 BVH_ALWAYS_INLINE Vec<T, N> fast_mul_add(const Vec<T, N>& a, const Vec<T, N>& b, const Vec<T, N>& c) {
0113     return Vec<T, N>::generate([&] (size_t i) { return fast_mul_add(a[i], b[i], c[i]); });
0114 }
0115 
0116 template <typename T, size_t N>
0117 BVH_ALWAYS_INLINE Vec<T, N> safe_inverse(const Vec<T, N>& v) {
0118     return Vec<T, N>::generate([&] (size_t i) { return safe_inverse(v[i]); });
0119 }
0120 
0121 template <typename T, size_t N>
0122 BVH_ALWAYS_INLINE T length(const Vec<T, N>& v) {
0123     return std::sqrt(dot(v, v));
0124 }
0125 
0126 template <typename T, size_t N>
0127 BVH_ALWAYS_INLINE Vec<T, N> normalize(const Vec<T, N>& v) {
0128     return v * (static_cast<T>(1.) / length(v));
0129 }
0130 
0131 } // namespace bvh::v2
0132 
0133 #endif