MeshLib C++ Docs
Loading...
Searching...
No Matches
MRRayBoxIntersection.h
Go to the documentation of this file.
1#pragma once
2#include "MRBox.h"
4#include "MRMesh/MRMacros.h"
5#include "MRPch/MRBindingMacros.h"
6
7namespace MR
8{
9
13
14template<typename T>
16{
17 // This is hidden to match the specialization below.
19 RayOrigin( const Vector3<T> & ro ) : p( ro ) { }
20};
21
22/* CPU(X86_64) - AMD64 / Intel64 / x86_64 64-bit */
23#if defined(__x86_64__) || defined(_M_X64)
24template<>
25struct RayOrigin<float>
26{
27 MR_BIND_IGNORE __m128 p;
28 RayOrigin( const Vector3f & ro ) { p = _mm_set_ps( ro.x, ro.y, ro.z, 0 ); }
29};
30#endif
31
35template <typename T = float>
36bool 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
87template <typename T = float>
88bool rayBoxIntersect( const Box3<T>& box, const Line3<T>& line, T t0, T t1 )
89{
90 IntersectionPrecomputes<T> prec( line.d );
91 return rayBoxIntersect( box, RayOrigin<T>( line.p ), t0, t1, prec );
92}
93
95
96}
Vector3i sign
stores signs of direction vector;
Definition MRIntersectionPrecomputes.h:127
Vector3< T > invDir
Definition MRIntersectionPrecomputes.h:119
bool rayBoxIntersect(const Box3< T > &box, const RayOrigin< T > &rayOrigin, T &t0, T &t1, const IntersectionPrecomputes< T > &prec)
Definition MRRayBoxIntersection.h:36
Definition MRCameraOrientationPlugin.h:8
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:10
Box given by its min- and max- corners.
Definition MRMesh/MRBox.h:27
V max
Definition MRMesh/MRBox.h:35
V min
Definition MRMesh/MRBox.h:35
Definition MRMeshFwd.h:503
Definition MRLine.h:13
Definition MRRayBoxIntersection.h:16
RayOrigin(const Vector3< T > &ro)
Definition MRRayBoxIntersection.h:19
MR_BIND_IGNORE Vector3< T > p
Definition MRRayBoxIntersection.h:18
Definition MRMesh/MRVector3.h:30