13#ifndef EBGEOMETRY_TRIANGLERAY_HPP
14#define EBGEOMETRY_TRIANGLERAY_HPP
27namespace TriangleRay {
49template <
class V,
class Source>
57 const V a_tMax)
noexcept
62 using TriangleDistance::constant;
63 using TriangleDistance::cross;
64 using TriangleDistance::dot;
69 const Vec3V<V> v0 = a_triangle.vertex(0);
70 const Vec3V<V> e1 = a_triangle.vertex(1) - v0;
71 const Vec3V<V> e2 = a_triangle.vertex(2) - v0;
73 const Vec3V<V> pv =
cross(a_direction, e2);
74 const V det =
dot(e1, pv);
75 const V inv = constant<V>(1) / det;
77 const Vec3V<V> s = a_origin - v0;
78 const V u =
dot(s, pv) * inv;
80 const Vec3V<V> q =
cross(s, e1);
81 const V v =
dot(a_direction, q) * inv;
82 const V t =
dot(e2, q) * inv;
92 const Vec3V<V> n =
cross(e1, e2);
93 const V nx = abs(n.x);
94 const V ny = abs(n.y);
95 const V nz = abs(n.z);
96 const V nxy = select(nx > ny, nx, ny);
97 const V area2 = select(nxy > nz, nxy, nz);
99 const V delta = ulps * (abs(a_origin.x) + abs(a_origin.y) + abs(a_origin.z) + abs(v0.x) + abs(v0.y) + abs(v0.z));
100 const V slack = ulps * area2 + delta * (abs(e1.x) + abs(e1.y) + abs(e1.z) + abs(e2.x) + abs(e2.y) + abs(e2.z));
102 const auto inside = both(both(u * area2 + slack >= constant<V>(0), v * area2 + slack >= constant<V>(0)),
103 (constant<V>(1) - u - v) * area2 + slack >= constant<V>(0));
104 const auto inRange = both(t >= a_tMin, a_tMax >= t);
105 const auto crosses = both(both(inside, inRange), abs(det) > constant<V>(0));
GPU portability layer: host/device decoration macros and backend detection.
#define EBGEOMETRY_HOST_ALWAYS_INLINE
Always inline a function in a host pass (GCC and Clang); nothing in a device pass.
Definition EBGeometry_GPU.hpp:123
#define EBGEOMETRY_HOST_DEVICE
Mark a function as callable from both host and device code (no-op on host compilers).
Definition EBGeometry_GPU.hpp:80
Scalar helpers and numeric limits that compile for both host and device.
Thin wrappers over SSE4.1, AVX and AVX-512 registers, so that one kernel template serves every SIMD w...
The triangle distance kernels, written once for a scalar and for every SIMD::Pack.
bool both(const bool a_lhs, const bool a_rhs) noexcept
Whether both conditions hold (scalar form).
Definition EBGeometry_SIMD.hpp:62
T select(const bool a_mask, const T a_ifTrue, const T a_ifFalse) noexcept
Pick a_ifTrue where a_mask holds, else a_ifFalse (scalar form).
Definition EBGeometry_SIMD.hpp:49
float abs(const float a_x) noexcept
Absolute value (scalar form).
Definition EBGeometry_SIMD.hpp:98
EBGEOMETRY_HOST_ALWAYS_INLINE V crossing(const Source &a_triangle, const TriangleDistance::Vec3V< V > &a_origin, const TriangleDistance::Vec3V< V > &a_direction, const V a_tMin, const V a_tMax) noexcept
Where a ray crosses a triangle, or one triangle per lane (Möller–Trumbore).
Definition EBGeometry_TriangleRay.hpp:53
Namespace containing all of EBGeometry's functionality.
Definition EBGeometry_Affine.hpp:26
constexpr Vec3T< T > cross(const Vec3T< T > &u, const Vec3T< T > &v) noexcept
Cross product of two 3D vectors.
T dot(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Dot product of two 2D vectors.
Numeric limits, with the meanings of the std::numeric_limits members of the same names.
Definition EBGeometry_Math.hpp:91
V type
The scalar type.
Definition EBGeometry_SIMD.hpp:177
A 3D vector of V, where V is a scalar or a SIMD::Pack: x, y and z each hold one lane per triangle.
Definition EBGeometry_TriangleDistance.hpp:39