| 34 | /// see "An Efficient and Robust Ray-Box Intersection Algorithm" at https://people.csail.mit.edu/amy/papers/box-jgt.pdf |
| 35 | template <typename T = float> |
| 36 | bool rayBoxIntersect( const Box3<T>& box, const RayOrigin<T> & rayOrigin, T & t0, T & t1, const IntersectionPrecomputes<T>& prec ) |
| 37 | { |
| 38 | #if defined(__x86_64__) || defined(_M_X64) |
| 39 | if constexpr (std::is_same_v<T, float>) |
| 40 | { |
| 41 | __m128 l = _mm_set_ps( box.min.x, box.min.y, box.min.z, t0 ); |
| 42 | __m128 r = _mm_set_ps( box.max.x, box.max.y, box.max.z, t1 ); |
| 43 | l = _mm_sub_ps( l, rayOrigin.p ); |
| 44 | r = _mm_sub_ps( r, rayOrigin.p ); |
| 45 | l = _mm_mul_ps( l, prec.invDir ); |
| 46 | r = _mm_mul_ps( r, prec.invDir ); |
| 47 | |
| 48 | __m128 a = _mm_min_ps( l, r ); |
| 49 | __m128 b = _mm_max_ps( l, r ); |
| 50 | |
| 51 | __m128 aa = _mm_movehl_ps( a, a ); |
| 52 | aa = _mm_max_ps( aa, a ); |
| 53 | __m128 aaa = _mm_shuffle_ps( aa, aa, 1 ); |
| 54 | aaa = _mm_max_ss( aaa, aa ); |
| 55 | t0 = _mm_cvtss_f32( aaa ); |
| 56 | |
| 57 | __m128 bb = _mm_movehl_ps( b, b ); |
| 58 | bb = _mm_min_ps( bb, b ); |
| 59 | __m128 bbb = _mm_shuffle_ps( bb, bb, 1 ); |
| 60 | bbb = _mm_min_ss( bbb, bb ); |
| 61 | t1 = _mm_cvtss_f32( bbb ); |
| 62 | |
| 63 | return t0 <= t1; |
| 64 | } |
| 65 | else |
| 66 | #else |
| 67 | #pragma message("rayBoxIntersect: no hardware optimized instructions") |
| 68 | #endif |
| 69 | { |
| 70 | const Vector3i& sign = prec.sign; |
| 71 | |
| 72 | // compare and update x-dimension with t0-t1 |
| 73 | t1 = std::min( (box[sign.x].x - rayOrigin.p.x) * prec.invDir.x, t1 ); |
| 74 | t0 = std::max( (box[1 - sign.x].x - rayOrigin.p.x) * prec.invDir.x, t0 ); |
| 75 | |
| 76 | // compare and update y-dimension with t0-t1 |
| 77 | t1 = std::min( (box[sign.y].y - rayOrigin.p.y) * prec.invDir.y, t1 ); |
| 78 | t0 = std::max( (box[1 - sign.y].y - rayOrigin.p.y) * prec.invDir.y, t0 ); |
| 79 | |
| 80 | // compare and update z-dimension with t0-t1 |
| 81 | t1 = std::min( (box[sign.z].z - rayOrigin.p.z) * prec.invDir.z, t1 ); |
| 82 | t0 = std::max( (box[1 - sign.z].z - rayOrigin.p.z) * prec.invDir.z, t0 ); |
| 83 | return t0 <= t1; |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | template <typename T = float> |
| 88 | bool rayBoxIntersect( const Box3<T>& box, const Line3<T>& line, T t0, T t1 ) |
no test coverage detected