From 40ad1cf0b1203848508cf6389e4337eb5071edf6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 14 Nov 2017 16:10:48 +1100 Subject: BLI: sync changes from 2.8 --- source/blender/blenlib/BLI_listbase.h | 1 + source/blender/blenlib/BLI_math_color.h | 4 + source/blender/blenlib/BLI_math_matrix.h | 1 + source/blender/blenlib/BLI_math_vector.h | 3 + source/blender/blenlib/BLI_rand.h | 12 +++ source/blender/blenlib/BLI_utildefines.h | 3 + source/blender/blenlib/intern/listbase.c | 28 ++++++ source/blender/blenlib/intern/math_color_inline.c | 8 ++ source/blender/blenlib/intern/math_matrix.c | 10 ++ source/blender/blenlib/intern/math_vector.c | 14 +++ source/blender/blenlib/intern/math_vector_inline.c | 14 +++ source/blender/blenlib/intern/rand.c | 101 +++++++++++++++++++++ 12 files changed, 199 insertions(+) diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index b06944e4985..c1e28d5ebc3 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -77,6 +77,7 @@ int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); +void BLI_listbases_swaplinks(struct ListBase *listbasea, struct ListBase *listbaseb, void *vlinka, void *vlinkb) ATTR_NONNULL(2, 3); void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2); diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 5e6b1256d30..34fc52c12c0 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -141,7 +141,11 @@ MINLINE void float_to_byte_dither_v3(unsigned char b[3], const float f[3], float #define rgba_char_args_set_fl(col, r, g, b, a) \ rgba_char_args_set(col, (r) * 255, (g) * 255, (b) * 255, (a) * 255) +#define rgba_float_args_set_ch(col, r, g, b, a) \ + rgba_float_args_set(col, (r) / 255.0f, (g) / 255.0f, (b) / 255.0f, (a) / 255.0f) + MINLINE void rgba_char_args_set(char col[4], const char r, const char g, const char b, const char a); +MINLINE void rgba_float_args_set(float col[4], const float r, const float g, const float b, const float a); MINLINE void rgba_char_args_test_set(char col[4], const char r, const char g, const char b, const char a); MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack); diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index d0dfad2a02f..173ef6861e6 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -210,6 +210,7 @@ void scale_m4_fl(float R[4][4], float scale); float mat3_to_scale(float M[3][3]); float mat4_to_scale(float M[4][4]); +float mat4_to_xy_scale(float M[4][4]); void size_to_mat3(float R[3][3], const float size[3]); void size_to_mat4(float R[4][4], const float size[3]); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 4fdb33926a2..3f603311530 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -151,6 +151,7 @@ MINLINE void negate_v3_short(short r[3]); MINLINE void negate_v3_db(double r[3]); MINLINE void invert_v2(float r[2]); +MINLINE void invert_v3(float r[3]); MINLINE void abs_v2(float r[2]); MINLINE void abs_v2_v2(float r[2], const float a[2]); @@ -311,6 +312,7 @@ void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]); void ortho_v3_v3(float out[3], const float v[3]); void ortho_v2_v2(float out[2], const float v[2]); void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]); +void rotate_v2_v2fl(float r[2], const float p[2], const float angle); void rotate_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle); void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], const float angle); @@ -326,6 +328,7 @@ void print_vn(const char *str, const float v[], const int n); #define print_v4_id(v) print_v4(STRINGIFY(v), v) #define print_vn_id(v, n) print_vn(STRINGIFY(v), v, n) +MINLINE void normal_float_to_short_v2(short r[2], const float n[2]); MINLINE void normal_short_to_float_v3(float r[3], const short n[3]); MINLINE void normal_float_to_short_v3(short r[3], const float n[3]); diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index f36d2faa1b8..69b23b2473f 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -101,4 +101,16 @@ RNG_THREAD_ARRAY *BLI_rng_threaded_new(void); void BLI_rng_threaded_free(struct RNG_THREAD_ARRAY *rngarr) ATTR_NONNULL(1); int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread) ATTR_WARN_UNUSED_RESULT; +/** Low-discrepancy sequences **/ + +/** Return the _n_th number of the given low-discrepancy sequence. */ +void BLI_halton_1D(unsigned int prime, double offset, int n, double *r); +void BLI_halton_2D(unsigned int prime[2], double offset[2], int n, double *r); +void BLI_halton_3D(unsigned int prime[3], double offset[3], int n, double *r); +void BLI_hammersley_1D(unsigned int n, double *r); + +/** Return the whole low-discrepancy sequence up to _n_. */ +void BLI_halton_2D_sequence(unsigned int prime[2], double offset[2], int n, double *r); +void BLI_hammersley_2D_sequence(unsigned int n, double *r); + #endif /* __BLI_RAND_H__ */ diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 66c7f247f61..1186e4a0713 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -651,6 +651,9 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size); # define BLI_STATIC_ASSERT(a, msg) #endif +#define BLI_STATIC_ASSERT_ALIGN(st, align) \ + BLI_STATIC_ASSERT((sizeof(st) % (align) == 0), "Structure must be strictly aligned") + /* hints for branch prediction, only use in code that runs a _lot_ where */ #ifdef __GNUC__ # define LIKELY(x) __builtin_expect(!!(x), 1) diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 46dcee48eda..0a6d575c7d6 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -169,6 +169,34 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) else if (listbase->first == linkb) listbase->first = linka; } +/** + * Swaps \a vlinka and \a vlinkb from their respective lists. Assumes they are both already in their lista! + */ +void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb) +{ + Link *linka = vlinka; + Link *linkb = vlinkb; + Link linkc = {NULL}; + + if (!linka || !linkb) { + return; + } + + /* Temporary link to use as placeholder of the links positions */ + BLI_insertlinkafter(listbasea, linka, &linkc); + + /* Bring linka into linkb position */ + BLI_remlink(listbasea, linka); + BLI_insertlinkafter(listbaseb, linkb, linka); + + /* Bring linkb into linka position */ + BLI_remlink(listbaseb, linkb); + BLI_insertlinkafter(listbasea, &linkc, linkb); + + /* Remove temporary link */ + BLI_remlink(listbasea, &linkc); +} + /** * Removes the head from \a listbase and returns it. */ diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c index 01a805a09b6..bc3a1ee3e90 100644 --- a/source/blender/blenlib/intern/math_color_inline.c +++ b/source/blender/blenlib/intern/math_color_inline.c @@ -239,6 +239,14 @@ MINLINE void rgba_char_args_set(char col[4], const char r, const char g, const c col[3] = a; } +MINLINE void rgba_float_args_set(float col[4], const float r, const float g, const float b, const float a) +{ + col[0] = r; + col[1] = g; + col[2] = b; + col[3] = a; +} + MINLINE void rgba_char_args_test_set(char col[4], const char r, const char g, const char b, const char a) { if (col[3] == 0) { diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index d1a219c196a..311d963f64d 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -1523,6 +1523,15 @@ float mat4_to_scale(float mat[4][4]) return len_v3(unit_vec); } +/** Return 2D scale (in XY plane) of given mat4. */ +float mat4_to_xy_scale(float M[4][4]) +{ + /* unit length vector in xy plane */ + float unit_vec[3] = {(float)M_SQRT1_2, (float)M_SQRT1_2, 0.0f}; + mul_mat3_m4_v3(M, unit_vec); + return len_v3(unit_vec); +} + void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) { /* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */ @@ -1625,6 +1634,7 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz) mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]); } +/* TODO: enum for axis? */ /** * Rotate a matrix in-place. * diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 5f44c93e169..05562502278 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -849,6 +849,20 @@ void ortho_v2_v2(float out[2], const float v[2]) out[1] = v[0]; } +/** + * Rotate a point \a p by \a angle around origin (0, 0) + */ +void rotate_v2_v2fl(float r[2], const float p[2], const float angle) +{ + const float co = cosf(angle); + const float si = sinf(angle); + + BLI_assert(r != p); + + r[0] = co * p[0] - si * p[1]; + r[1] = si * p[0] + co * p[1]; +} + /** * Rotate a point \a p by \a angle around an arbitrary unit length \a axis. * http://local.wasp.uwa.edu.au/~pbourke/geometry/ diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index ee5e8651bd3..08687a1ab47 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -658,6 +658,14 @@ MINLINE void invert_v2(float r[2]) r[1] = 1.0f / r[1]; } +MINLINE void invert_v3(float r[3]) +{ + BLI_assert(!ELEM(0.0f, r[0], r[1], r[2])); + r[0] = 1.0f / r[0]; + r[1] = 1.0f / r[1]; + r[2] = 1.0f / r[2]; +} + MINLINE void abs_v2(float r[2]) { r[0] = fabsf(r[0]); @@ -960,6 +968,12 @@ MINLINE float normalize_v3(float n[3]) return normalize_v3_v3(n, n); } +MINLINE void normal_float_to_short_v2(short out[2], const float in[2]) +{ + out[0] = (short) (in[0] * 32767.0f); + out[1] = (short) (in[1] * 32767.0f); +} + MINLINE void normal_short_to_float_v3(float out[3], const short in[3]) { out[0] = in[0] * (1.0f / 32767.0f); diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 40d9a3da3d9..1a178db1413 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -41,6 +41,9 @@ #include "BLI_rand.h" #include "BLI_math.h" +/* defines BLI_INLINE */ +#include "BLI_utildefines.h" + #include "BLI_sys_types.h" #include "BLI_strict_flags.h" @@ -353,3 +356,101 @@ int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread) return BLI_rng_get_int(&rngarr->rng_tab[thread]); } +/* ********* Low-discrepancy sequences ************** */ + +/* incremental halton sequence generator, from: + * "Instant Radiosity", Keller A. */ +BLI_INLINE double halton_ex(double invprimes, double *offset) +{ + double e = fabs((1.0 - *offset) - 1e-10); + + if (invprimes >= e) { + double lasth; + double h = invprimes; + + do { + lasth = h; + h *= invprimes; + } while (h >= e); + + *offset += ((lasth + h) - 1.0); + } + else { + *offset += invprimes; + } + + return *offset; +} + +void BLI_halton_1D(unsigned int prime, double offset, int n, double *r) +{ + const double invprime = 1.0 / (double)prime; + + for (int s = 0; s < n; s++) { + *r = halton_ex(invprime, &offset); + } +} + +void BLI_halton_2D(unsigned int prime[2], double offset[2], int n, double *r) +{ + const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]}; + + for (int s = 0; s < n; s++) { + for (int i = 0; i < 2; i++) { + r[i] = halton_ex(invprimes[i], &offset[i]); + } + } +} + +void BLI_halton_3D(unsigned int prime[3], double offset[3], int n, double *r) +{ + const double invprimes[3] = {1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]}; + + for (int s = 0; s < n; s++) { + for (int i = 0; i < 3; i++) { + r[i] = halton_ex(invprimes[i], &offset[i]); + } + } +} + +void BLI_halton_2D_sequence(unsigned int prime[2], double offset[2], int n, double *r) +{ + const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]}; + + for (int s = 0; s < n; s++) { + for (int i = 0; i < 2; i++) { + r[s * 2 + i] = halton_ex(invprimes[i], &offset[i]); + } + } +} + + +/* From "Sampling with Hammersley and Halton Points" TT Wong + * Appendix: Source Code 1 */ +BLI_INLINE double radical_inverse(unsigned int n) +{ + double u = 0; + + /* This reverse the bitwise representation + * around the decimal point. */ + for (double p = 0.5; n; p *= 0.5, n >>= 1) { + if (n & 1) { + u += p; + } + } + + return u; +} + +void BLI_hammersley_1D(unsigned int n, double *r) +{ + *r = radical_inverse(n); +} + +void BLI_hammersley_2D_sequence(unsigned int n, double *r) +{ + for (unsigned int s = 0; s < n; s++) { + r[s * 2 + 0] = (double)(s + 0.5) / (double)n; + r[s * 2 + 1] = radical_inverse(s); + } +} -- cgit v1.2.3