Blender V4.3
math_float3.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2013 Intel Corporation
2 * SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0 */
5
6#ifndef __UTIL_MATH_FLOAT3_H__
7#define __UTIL_MATH_FLOAT3_H__
8
9#ifndef __UTIL_MATH_H__
10# error "Do not include this file directly, include util/types.h instead."
11#endif
12
14
16{
17#ifdef __KERNEL_SSE__
18 return float3(_mm_setzero_ps());
19#else
20 return make_float3(0.0f, 0.0f, 0.0f);
21#endif
22}
23
25{
26 return make_float3(1.0f, 1.0f, 1.0f);
27}
28
29#if defined(__KERNEL_METAL__)
30
32{
33 return make_float3(1.0f / a.x, 1.0f / a.y, 1.0f / a.z);
34}
35
36#else
37
39{
40# ifdef __KERNEL_SSE__
41 return float3(_mm_xor_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))));
42# else
43 return make_float3(-a.x, -a.y, -a.z);
44# endif
45}
46
48{
49# ifdef __KERNEL_SSE__
50 return float3(_mm_mul_ps(a.m128, b.m128));
51# else
52 return make_float3(a.x * b.x, a.y * b.y, a.z * b.z);
53# endif
54}
55
57{
58# ifdef __KERNEL_SSE__
59 return float3(_mm_mul_ps(a.m128, _mm_set1_ps(f)));
60# else
61 return make_float3(a.x * f, a.y * f, a.z * f);
62# endif
63}
64
66{
67# if defined(__KERNEL_SSE__)
68 return float3(_mm_mul_ps(_mm_set1_ps(f), a.m128));
69# else
70 return make_float3(a.x * f, a.y * f, a.z * f);
71# endif
72}
73
75{
76# if defined(__KERNEL_SSE__)
77 return float3(_mm_div_ps(_mm_set1_ps(f), a.m128));
78# else
79 return make_float3(f / a.x, f / a.y, f / a.z);
80# endif
81}
82
84{
85# if defined(__KERNEL_SSE__)
86 return float3(_mm_div_ps(a.m128, _mm_set1_ps(f)));
87# else
88 float invf = 1.0f / f;
89 return make_float3(a.x * invf, a.y * invf, a.z * invf);
90# endif
91}
92
94{
95# if defined(__KERNEL_SSE__)
96 return float3(_mm_div_ps(a.m128, b.m128));
97# else
98 return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
99# endif
100}
101
103{
104# ifdef __KERNEL_SSE__
105 return float3(_mm_add_ps(a.m128, b.m128));
106# else
107 return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
108# endif
109}
110
112{
113 return a + make_float3(f, f, f);
114}
115
117{
118# ifdef __KERNEL_SSE__
119 return float3(_mm_sub_ps(a.m128, b.m128));
120# else
121 return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
122# endif
123}
124
126{
127 return a - make_float3(f, f, f);
128}
129
131{
132 return a = a + b;
133}
134
136{
137 return a = a - b;
138}
139
141{
142 return a = a * b;
143}
144
146{
147 return a = a * f;
148}
149
151{
152 return a = a / b;
153}
154
156{
157 float invf = 1.0f / f;
158 return a = a * invf;
159}
160
161# if !(defined(__KERNEL_METAL__) || defined(__KERNEL_CUDA__) || defined(__KERNEL_HIP__) || \
162 defined(__KERNEL_ONEAPI__))
164{
165 a = float3(a) * b;
166 return a;
167}
168
170{
171 a = float3(a) * f;
172 return a;
173}
174
176{
177 a = float3(a) / b;
178 return a;
179}
180
182{
183 a = float3(a) / f;
184 return a;
185}
186# endif
187
189{
190# ifdef __KERNEL_SSE__
191 return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 7) == 7;
192# else
193 return (a.x == b.x && a.y == b.y && a.z == b.z);
194# endif
195}
196
198{
199 return !(a == b);
200}
201
202ccl_device_inline float dot(const float3 a, const float3 b)
203{
204# if defined(__KERNEL_SSE42__) && defined(__KERNEL_SSE__)
205 return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7F));
206# else
207 return a.x * b.x + a.y * b.y + a.z * b.z;
208# endif
209}
210
211#endif
212
214{
215#if defined(__KERNEL_SSE42__) && defined(__KERNEL_SSE__)
216 return _mm_cvtss_f32(_mm_hadd_ps(_mm_mul_ps(a, b), b));
217#else
218 return a.x * b.x + a.y * b.y;
219#endif
220}
221
223{
224#if defined(__KERNEL_SSE42__) && defined(__KERNEL_SSE__)
225 return _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(a.m128, a.m128, 0x7F)));
226#else
227 return sqrtf(dot(a, a));
228#endif
229}
230
232{
233 return min(min(a.x, a.y), a.z);
234}
235
237{
238 return max(max(a.x, a.y), a.z);
239}
240
242{
243 return dot(a, a);
244}
245
246#ifndef __KERNEL_METAL__
247
249{
250 return len(a - b);
251}
252
254{
255# ifdef __KERNEL_SSE__
256 const float4 x = float4(a.m128);
257 const float4 y = shuffle<1, 2, 0, 3>(float4(b.m128));
258 const float4 z = float4(_mm_mul_ps(shuffle<1, 2, 0, 3>(float4(a.m128)), float4(b.m128)));
259
260 return float3(shuffle<1, 2, 0, 3>(msub(x, y, z)).m128);
261# else
262 return make_float3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
263# endif
264}
265
267{
268# if defined(__KERNEL_SSE42__) && defined(__KERNEL_SSE__)
269 __m128 norm = _mm_sqrt_ps(_mm_dp_ps(a.m128, a.m128, 0x7F));
270 return float3(_mm_div_ps(a.m128, norm));
271# else
272 return a / len(a);
273# endif
274}
275
277{
278# ifdef __KERNEL_SSE__
279 return float3(_mm_min_ps(a.m128, b.m128));
280# else
281 return make_float3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
282# endif
283}
284
286{
287# ifdef __KERNEL_SSE__
288 return float3(_mm_max_ps(a.m128, b.m128));
289# else
290 return make_float3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
291# endif
292}
293
294ccl_device_inline float3 clamp(const float3 a, const float3 mn, const float3 mx)
295{
296 return min(max(a, mn), mx);
297}
298
300{
301# ifdef __KERNEL_SSE__
302# ifdef __KERNEL_NEON__
303 return float3(vabsq_f32(a.m128));
304# else
305 __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
306 return float3(_mm_and_ps(a.m128, mask));
307# endif
308# else
309 return make_float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
310# endif
311}
312
313ccl_device_inline float3 fmod(const float3 a, const float b)
314{
315 return make_float3(fmodf(a.x, b), fmodf(a.y, b), fmodf(a.z, b));
316}
317
319{
320# ifdef __KERNEL_SSE__
321 return float3(_mm_sqrt_ps(a));
322# else
323 return make_float3(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z));
324# endif
325}
326
328{
329# ifdef __KERNEL_SSE__
330 return float3(_mm_floor_ps(a));
331# else
332 return make_float3(floorf(a.x), floorf(a.y), floorf(a.z));
333# endif
334}
335
337{
338# ifdef __KERNEL_SSE__
339 return float3(_mm_ceil_ps(a));
340# else
341 return make_float3(ceilf(a.x), ceilf(a.y), ceilf(a.z));
342# endif
343}
344
345ccl_device_inline float3 mix(const float3 a, const float3 b, float t)
346{
347 return a + t * (b - a);
348}
349
351{
352# ifdef __KERNEL_SSE__
353 /* Don't use _mm_rcp_ps due to poor precision. */
354 return float3(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
355# else
356 return make_float3(1.0f / a.x, 1.0f / a.y, 1.0f / a.z);
357# endif
358}
359
364
366{
367 return make_float3(expf(v.x), expf(v.y), expf(v.z));
368}
369
371{
372 return make_float3(logf(v.x), logf(v.y), logf(v.z));
373}
374
376{
377 return make_float3(cosf(v.x), cosf(v.y), cosf(v.z));
378}
379
380ccl_device_inline float3 reflect(const float3 incident, const float3 unit_normal)
381{
382 return incident - 2.0f * unit_normal * dot(incident, unit_normal);
383}
384
385ccl_device_inline float3 refract(const float3 incident, const float3 normal, const float eta)
386{
387 float k = 1.0f - eta * eta * (1.0f - dot(normal, incident) * dot(normal, incident));
388 if (k < 0.0f)
389 return zero_float3();
390 else
391 return eta * incident - (eta * dot(normal, incident) + sqrt(k)) * normal;
392}
393
395 const float3 incident,
396 const float3 reference)
397{
398 return (dot(reference, incident) < 0.0f) ? vector : -vector;
399}
400#endif
401
403{
404 float len_squared = dot(v_proj, v_proj);
405 return (len_squared != 0.0f) ? (dot(v, v_proj) / len_squared) * v_proj : zero_float3();
406}
407
409{
410 *t = len(a);
411 float x = 1.0f / *t;
412 return a * x;
413}
414
416{
417 float t = len(a);
418 return (t != 0.0f) ? a * (1.0f / t) : a;
419}
420
422{
423 float t = len(a);
424 return (t != 0.0f) ? a * (1.0f / t) : fallback;
425}
426
428{
429 *t = len(a);
430 return (*t != 0.0f) ? a / (*t) : a;
431}
432
434{
435 return make_float3((b.x != 0.0f) ? a.x / b.x : 0.0f,
436 (b.y != 0.0f) ? a.y / b.y : 0.0f,
437 (b.z != 0.0f) ? a.z / b.z : 0.0f);
438}
439
441{
442 return (b != 0.0f) ? a / b : zero_float3();
443}
444
446{
447 return a + t * (b - a);
448}
449
451{
452 return a * a;
453}
454
456{
457#ifdef __KERNEL_SSE__
458 return a == make_float3(0.0f);
459#else
460 return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f);
461#endif
462}
463
465{
466#if defined(__KERNEL_SSE__) && defined(__KERNEL_NEON__)
467 __m128 t = a.m128;
468 t = vsetq_lane_f32(0.0f, t, 3);
469 return vaddvq_f32(t);
470#else
471 return (a.x + a.y + a.z);
472#endif
473}
474
476{
477 return reduce_add(a) * (1.0f / 3.0f);
478}
479
481{
482#if defined(__KERNEL_METAL__)
483 return all(a == b);
484#else
485 return a == b;
486#endif
487}
488
489/* Consistent name for this would be pow, but HIP compiler crashes in name mangling. */
491{
492 return make_float3(powf(v.x, e), powf(v.y, e), powf(v.z, e));
493}
494
499
501{
502 if (!isfinite_safe(v.x))
503 v.x = 0.0f;
504 if (!isfinite_safe(v.y))
505 v.y = 0.0f;
506 if (!isfinite_safe(v.z))
507 v.z = 0.0f;
508 return v;
509}
510
512
513#endif /* __UTIL_MATH_FLOAT3_H__ */
#define saturate(a)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition btVector3.h:263
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
VecBase< float, 3 > float3
local_group_size(16, 16) .push_constant(Type b
#define logf(x)
#define cosf(x)
#define expf(x)
#define ccl_private
#define ccl_device_inline
#define powf(x, y)
#define CCL_NAMESPACE_END
#define saturatef(x)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define ceilf(x)
#define fmodf(x, y)
#define floorf(x)
#define fabsf(x)
#define sqrtf(x)
int len
#define mix(a, b, c)
Definition hash.h:36
ccl_device_inline float len_squared(const float2 a)
ccl_device_inline float3 sqrt(const float3 a)
ccl_device_inline float3 safe_normalize(const float3 a)
ccl_device_inline bool is_zero(const float3 a)
ccl_device_inline float3 floor(const float3 a)
ccl_device_inline float3 operator*(const float3 a, const float3 b)
Definition math_float3.h:47
ccl_device_inline bool isequal(const float3 a, const float3 b)
ccl_device_inline float3 safe_normalize_fallback(const float3 a, const float3 fallback)
ccl_device_inline float3 reflect(const float3 incident, const float3 unit_normal)
ccl_device_inline float3 refract(const float3 incident, const float3 normal, const float eta)
ccl_device_inline float3 cross(const float3 a, const float3 b)
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
ccl_device_inline float3 exp(float3 v)
ccl_device_inline float reduce_min(float3 a)
ccl_device_inline float3 faceforward(const float3 vector, const float3 incident, const float3 reference)
ccl_device_inline float3 normalize_len(const float3 a, ccl_private float *t)
ccl_device_inline float3 clamp(const float3 a, const float3 mn, const float3 mx)
ccl_device_inline float3 project(const float3 v, const float3 v_proj)
ccl_device_inline float3 sqr(float3 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
ccl_device_inline float3 power(float3 v, float e)
ccl_device_inline float3 operator/=(float3 &a, const float3 b)
ccl_device_inline float dot_xy(const float3 a, const float3 b)
ccl_device_inline float3 fmod(const float3 a, const float b)
ccl_device_inline float3 fabs(const float3 a)
ccl_device_inline float reduce_add(const float3 a)
ccl_device_inline float reduce_max(float3 a)
ccl_device_inline float3 ceil(const float3 a)
ccl_device_inline float3 operator+(const float3 a, const float3 b)
ccl_device_inline float3 rcp(const float3 a)
ccl_device_inline float average(const float3 a)
ccl_device_inline float3 operator*=(float3 &a, const float3 b)
ccl_device_inline float3 operator/(const float f, const float3 a)
Definition math_float3.h:74
ccl_device_inline bool operator==(const float3 a, const float3 b)
ccl_device_inline float distance(const float3 a, const float3 b)
ccl_device_inline float3 safe_divide(const float3 a, const float3 b)
ccl_device_inline float3 operator-(const float3 &a)
Definition math_float3.h:38
ccl_device_inline bool isfinite_safe(float3 v)
ccl_device_inline float3 safe_normalize_len(const float3 a, ccl_private float *t)
ccl_device_inline float3 interp(float3 a, float3 b, float t)
ccl_device_inline float3 operator-=(float3 &a, const float3 b)
ccl_device_inline float3 cos(float3 v)
ccl_device_inline bool operator!=(const float3 a, const float3 b)
ccl_device_inline float3 operator+=(float3 &a, const float3 b)
ccl_device_inline float3 log(float3 v)
ccl_device_inline float dot(const float3 a, const float3 b)
ccl_device_inline float len_squared(const float3 a)
ccl_device_inline float3 ensure_finite(float3 v)
ccl_device_inline float4 msub(const float4 a, const float4 b, const float4 c)
ccl_device_inline float4 mask(const int4 mask, const float4 a)
#define min(a, b)
Definition sort.c:32
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
VecBase< float, 4 > float4
float max