MeshLib C++ Docs
Loading...
Searching...
No Matches
MRIntersectionPrecomputes.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRVector3.h"
4#include "MRPch/MRBindingMacros.h"
5
6#if defined(__x86_64__) || defined(_M_X64)
7#include <xmmintrin.h>
8#elif defined(__aarch64__) || defined(_M_ARM64)
9#include <arm_neon.h>
10#elif defined(__wasm_simd128__)
11#include <wasm_simd128.h>
12#endif
13
14namespace MR
15{
16
19
28template <typename T>
29void findMaxVectorDim( int& dimX, int& dimY, int& dimZ, const Vector3<T>& dir )
30{
31 if( dir.x > dir.y )
32 {
33 if( dir.x > dir.z )
34 {
35 if( dir.y > dir.z )
36 {
38 if( -dir.z > dir.x )
39 {
40 dimZ = 2; dimX = 1; dimY = 0;
41 }
42 else
43 {
44 dimZ = 0; dimX = 1; dimY = 2;
45 }
46 }
47 else
48 {
50 if( -dir.y > dir.x )
51 {
52 dimZ = 1; dimX = 0; dimY = 2;
53 }
54 else
55 {
56 dimZ = 0; dimX = 1; dimY = 2;
57 }
58 }
59 }
60 else
61 {
63 if( -dir.y > dir.z )
64 {
65 dimZ = 1; dimX = 0; dimY = 2;
66 }
67 else
68 {
69 dimZ = 2; dimX = 0; dimY = 1;
70 }
71 }
72 }
73 else
74 {
75 if( dir.y > dir.z )
76 {
77 if( dir.x < dir.z )
78 {
80 if( -dir.x > dir.y )
81 {
82 dimZ = 0; dimX = 2; dimY = 1;
83 }
84 else
85 {
86 dimZ = 1; dimX = 2; dimY = 0;
87 }
88 }
89 else
90 {
92 if( -dir.z > dir.y )
93 {
94 dimZ = 2; dimX = 1; dimY = 0;
95 }
96 else
97 {
98 dimZ = 1; dimX = 2; dimY = 0;
99 }
100 }
101 }
102 else
103 {
105 if( -dir.x > dir.z )
106 {
107 dimZ = 0; dimX = 2; dimY = 1;
108 }
109 else
110 {
111 dimZ = 2; dimX = 0; dimY = 1;
112 }
113 }
114 }
115}
116
119template<typename T>
121{
126 int maxDimIdxZ = 2;
127 int idxX = 0;
128 int idxY = 1;
129
132
134 T Sx, Sy, Sz;
137 {
139
140 sign.x = dir.x >= T( 0 ) ? 1 : 0;
141 sign.y = dir.y >= T( 0 ) ? 1 : 0;
142 sign.z = dir.z >= T( 0 ) ? 1 : 0;
143
144 Sx = dir[idxX] / dir[maxDimIdxZ];
145 Sy = dir[idxY] / dir[maxDimIdxZ];
146 Sz = T( 1 ) / dir[maxDimIdxZ];
147
148 invDir.x = ( dir.x == 0 ) ? std::numeric_limits<T>::max() : T( 1 ) / dir.x;
149 invDir.y = ( dir.y == 0 ) ? std::numeric_limits<T>::max() : T( 1 ) / dir.y;
150 invDir.z = ( dir.z == 0 ) ? std::numeric_limits<T>::max() : T( 1 ) / dir.z;
151 }
152
153};
154
156#if defined(__x86_64__) || defined(_M_X64)
157template<>
158struct IntersectionPrecomputes<float>
159{
161 MR_BIND_IGNORE __m128 invDir;
164 int maxDimIdxZ = 2;
165 int idxX = 0;
166 int idxY = 1;
167
169 MR_BIND_IGNORE float Sx, Sy, Sz;
170
171 IntersectionPrecomputes() = default;
172 IntersectionPrecomputes( const Vector3<float>& dir )
173 {
175
176 Sx = dir[idxX] / dir[maxDimIdxZ];
177 Sy = dir[idxY] / dir[maxDimIdxZ];
178 Sz = float( 1 ) / dir[maxDimIdxZ];
179
180 invDir = _mm_set_ps(
181 1,
182 ( dir.z == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.z,
183 ( dir.y == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.y,
184 ( dir.x == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.x );
185 }
186
187};
188
190#elif defined(__aarch64__) || defined(_M_ARM64)
191
193MR_BIND_IGNORE inline float32x4_t toFloat32x4( float x, float y, float z, float w )
194{
195 const float a[4] = { x, y, z, w };
196 return vld1q_f32( a );
197}
198
199template<>
200struct IntersectionPrecomputes<float>
201{
203 MR_BIND_IGNORE float32x4_t invDir;
206 int maxDimIdxZ = 2;
207 int idxX = 0;
208 int idxY = 1;
209
211 MR_BIND_IGNORE float Sx, Sy, Sz;
212
213 IntersectionPrecomputes() = default;
214 IntersectionPrecomputes( const Vector3<float>& dir )
215 {
217
218 Sx = dir[idxX] / dir[maxDimIdxZ];
219 Sy = dir[idxY] / dir[maxDimIdxZ];
220 Sz = float( 1 ) / dir[maxDimIdxZ];
221
222 invDir = toFloat32x4(
223 ( dir.x == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.x,
224 ( dir.y == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.y,
225 ( dir.z == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.z,
226 1 );
227 }
228
229};
230
232#elif defined(__wasm_simd128__)
233template<>
234struct IntersectionPrecomputes<float>
235{
237 MR_BIND_IGNORE v128_t invDir;
240 int maxDimIdxZ = 2;
241 int idxX = 0;
242 int idxY = 1;
243
245 MR_BIND_IGNORE float Sx, Sy, Sz;
246
247 IntersectionPrecomputes() = default;
248 IntersectionPrecomputes( const Vector3<float>& dir )
249 {
251
252 Sx = dir[idxX] / dir[maxDimIdxZ];
253 Sy = dir[idxY] / dir[maxDimIdxZ];
254 Sz = float( 1 ) / dir[maxDimIdxZ];
255
256 invDir = wasm_f32x4_make(
257 ( dir.x == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.x,
258 ( dir.y == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.y,
259 ( dir.z == 0 ) ? std::numeric_limits<float>::max() : 1 / dir.z,
260 1 );
261 }
262
263};
264
265#else
266 #pragma message("IntersectionPrecomputes<float>: no hardware optimized instructions")
267#endif
268
270
271}
void findMaxVectorDim(int &dimX, int &dimY, int &dimZ, const Vector3< T > &dir)
finds index of maximum axis and stores it into dimZ
Definition MRIntersectionPrecomputes.h:29
T x
Definition MRVector3.h:39
T y
Definition MRVector3.h:39
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:13
T z
Definition MRVector3.h:39
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
Definition MRIntersectionPrecomputes.h:121
MR_BIND_IGNORE Vector3i sign
stores signs of direction vector;
Definition MRIntersectionPrecomputes.h:131
int idxY
Definition MRIntersectionPrecomputes.h:128
MR_BIND_IGNORE Vector3< T > invDir
{1 / dir}
Definition MRIntersectionPrecomputes.h:123
T Sx
precomputed factors
Definition MRIntersectionPrecomputes.h:134
int idxX
Definition MRIntersectionPrecomputes.h:127
T Sz
Definition MRIntersectionPrecomputes.h:134
IntersectionPrecomputes(const Vector3< T > &dir)
Definition MRIntersectionPrecomputes.h:136
T Sy
Definition MRIntersectionPrecomputes.h:134
int maxDimIdxZ
Definition MRIntersectionPrecomputes.h:126
Definition MRVector3.h:33