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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a vector
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
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 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)
#define min(a, b)
Definition sort.c:32
float max