58 assert( box.
valid() );
60 #if defined(__x86_64__) || defined(_M_X64)
61 if constexpr (std::is_same_v<T, float>)
64 static_assert(
sizeof( Box3f ) == 6 *
sizeof( float ) );
65 const float *
const c = &box.
min.x;
66 __m128 l = _mm_loadu_ps( c );
67 __m128 h = _mm_loadu_ps( c + 2 );
68 __m128 r = _mm_shuffle_ps( h, h, _MM_SHUFFLE( 3, 3, 2, 1 ) );
70 l = _mm_mul_ps( _mm_sub_ps( l, rayOrigin.p ), prec.
invDir );
71 r = _mm_mul_ps( _mm_sub_ps( r, rayOrigin.p ), prec.
invDir );
73 __m128 a = _mm_min_ps( l, r );
74 __m128 b = _mm_max_ps( l, r );
77 __m128 az = _mm_shuffle_ps( a, a, _MM_SHUFFLE( 2, 2, 2, 2 ) );
78 __m128 ay = _mm_shuffle_ps( a, a, _MM_SHUFFLE( 1, 1, 1, 1 ) );
79 t0 = _mm_cvtss_f32( _mm_max_ss( _mm_max_ss( _mm_max_ss( a, az ), ay ), _mm_load_ss( &t0 ) ) );
81 __m128 bz = _mm_shuffle_ps( b, b, _MM_SHUFFLE( 2, 2, 2, 2 ) );
82 __m128 by = _mm_shuffle_ps( b, b, _MM_SHUFFLE( 1, 1, 1, 1 ) );
83 t1 = _mm_cvtss_f32( _mm_min_ss( _mm_min_ss( _mm_min_ss( b, bz ), by ), _mm_load_ss( &t1 ) ) );
88 #elif defined(__aarch64__) || defined(_M_ARM64)
89 if constexpr (std::is_same_v<T, float>)
93 static_assert(
sizeof( Box3f ) == 6 *
sizeof( float ) );
94 const float *
const c = &box.
min.x;
95 float32x4_t h = vld1q_f32( c + 2 );
96 float32x4_t l = vsetq_lane_f32( t0, vld1q_f32( c ), 3 );
97 float32x4_t r = vsetq_lane_f32( t1, vextq_f32( h, h, 1 ), 3 );
99 l = vmulq_f32( vsubq_f32( l, rayOrigin.p ), prec.
invDir );
100 r = vmulq_f32( vsubq_f32( r, rayOrigin.p ), prec.
invDir );
102 t0 = vmaxvq_f32( vminq_f32( l, r ) );
103 t1 = vminvq_f32( vmaxq_f32( l, r ) );
108 #elif defined(__wasm_simd128__)
109 if constexpr (std::is_same_v<T, float>)
112 static_assert(
sizeof( Box3f ) == 6 *
sizeof( float ) );
113 const float *
const c = &box.
min.x;
114 v128_t l = wasm_v128_load( c );
115 v128_t h = wasm_v128_load( c + 2 );
116 v128_t r = wasm_i32x4_shuffle( h, h, 1, 2, 3, 3 );
118 l = wasm_f32x4_mul( wasm_f32x4_sub( l, rayOrigin.p ), prec.
invDir );
119 r = wasm_f32x4_mul( wasm_f32x4_sub( r, rayOrigin.p ), prec.
invDir );
121 v128_t a = wasm_f32x4_pmin( l, r );
122 v128_t b = wasm_f32x4_pmax( l, r );
126 v128_t az = wasm_i32x4_shuffle( a, a, 2, 2, 2, 2 );
127 v128_t ay = wasm_i32x4_shuffle( a, a, 1, 1, 1, 1 );
128 v128_t bz = wasm_i32x4_shuffle( b, b, 2, 2, 2, 2 );
129 v128_t by = wasm_i32x4_shuffle( b, b, 1, 1, 1, 1 );
131 t0 = std::max( t0, wasm_f32x4_extract_lane( wasm_f32x4_pmax( wasm_f32x4_pmax( a, az ), ay ), 0 ) );
132 t1 = std::min( t1, wasm_f32x4_extract_lane( wasm_f32x4_pmin( wasm_f32x4_pmin( b, bz ), by ), 0 ) );
138 #pragma message("rayBoxIntersect: no hardware optimized instructions")
141 const Vector3i& sign = prec.
sign;
144 t1 = std::min( (box[sign.x].x - rayOrigin.p.x) * prec.
invDir.x, t1 );
145 t0 = std::max( (box[1 - sign.x].x - rayOrigin.p.x) * prec.
invDir.x, t0 );
148 t1 = std::min( (box[sign.y].y - rayOrigin.p.y) * prec.
invDir.y, t1 );
149 t0 = std::max( (box[1 - sign.y].y - rayOrigin.p.y) * prec.
invDir.y, t0 );
152 t1 = std::min( (box[sign.z].z - rayOrigin.p.z) * prec.
invDir.z, t1 );
153 t0 = std::max( (box[1 - sign.z].z - rayOrigin.p.z) * prec.
invDir.z, t0 );