2023-05-31 16:19:06 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup bli
|
2011-02-27 20:37:56 +00:00
|
|
|
*/
|
|
|
|
|
|
2020-12-04 11:28:09 +01:00
|
|
|
#include <cmath>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <ctime>
|
2024-01-24 09:59:43 +01:00
|
|
|
#include <random>
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2005-07-25 20:33:10 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2021-06-28 19:25:40 +10:00
|
|
|
#include "BLI_bitmap.h"
|
2024-01-24 13:19:52 -05:00
|
|
|
#include "BLI_compiler_compat.h"
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 11:39:20 +03:00
|
|
|
#include "BLI_math_vector.h"
|
2024-12-05 14:36:01 +01:00
|
|
|
#include "BLI_noise.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_rand.h"
|
2020-07-10 15:53:36 +02:00
|
|
|
#include "BLI_rand.hh"
|
2024-02-14 13:40:31 +11:00
|
|
|
#include "BLI_sys_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_threads.h"
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2025-01-26 20:07:57 +01:00
|
|
|
#include "BLI_strict_flags.h" /* IWYU pragma: keep. Keep last. */
|
2014-03-30 13:12:33 +11:00
|
|
|
|
2019-02-23 17:47:33 +11:00
|
|
|
#define hash BLI_noise_hash_uchar_512
|
2011-05-10 14:48:06 +00:00
|
|
|
|
2014-04-02 09:57:48 +11:00
|
|
|
/**
|
|
|
|
|
* Random Number Generator.
|
|
|
|
|
*/
|
2005-07-25 20:56:48 +00:00
|
|
|
struct RNG {
|
2020-07-10 15:53:36 +02:00
|
|
|
blender::RandomNumberGenerator rng;
|
|
|
|
|
|
|
|
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("RNG")
|
2005-07-25 20:56:48 +00:00
|
|
|
};
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
RNG *BLI_rng_new(uint seed)
|
2005-07-25 20:33:10 +00:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
RNG *rng = new RNG();
|
|
|
|
|
rng->rng.seed(seed);
|
2005-07-25 20:33:10 +00:00
|
|
|
return rng;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
RNG *BLI_rng_new_srandom(uint seed)
|
2013-04-15 23:12:40 +00:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
RNG *rng = new RNG();
|
|
|
|
|
rng->rng.seed_random(seed);
|
2013-04-15 23:12:40 +00:00
|
|
|
return rng;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
void BLI_rng_free(RNG *rng)
|
2005-07-25 20:33:10 +00:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
delete rng;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_rng_seed(RNG *rng, uint seed)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
rng->rng.seed(seed);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_rng_srandom(RNG *rng, uint seed)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
rng->rng.seed_random(seed);
|
2014-07-20 00:38:52 +10:00
|
|
|
}
|
|
|
|
|
|
2016-06-12 00:38:49 +10:00
|
|
|
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
|
|
|
|
|
{
|
2022-09-25 18:30:50 +10:00
|
|
|
rng->rng.get_bytes(blender::MutableSpan(bytes, int64_t(bytes_len)));
|
2016-06-12 00:38:49 +10:00
|
|
|
}
|
|
|
|
|
|
2014-07-20 00:38:52 +10:00
|
|
|
int BLI_rng_get_int(RNG *rng)
|
|
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
return rng->rng.get_int32();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
uint BLI_rng_get_uint(RNG *rng)
|
2014-03-30 13:12:33 +11:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
return rng->rng.get_uint32();
|
2014-03-30 13:12:33 +11:00
|
|
|
}
|
|
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
double BLI_rng_get_double(RNG *rng)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
return rng->rng.get_double();
|
2005-07-25 20:33:10 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
float BLI_rng_get_float(RNG *rng)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
return rng->rng.get_float();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2015-01-09 11:54:51 +01:00
|
|
|
void BLI_rng_get_tri_sample_float_v2(
|
|
|
|
|
RNG *rng, const float v1[2], const float v2[2], const float v3[2], float r_pt[2])
|
|
|
|
|
{
|
2020-07-10 15:53:36 +02:00
|
|
|
copy_v2_v2(r_pt, rng->rng.get_triangle_sample(v1, v2, v3));
|
2015-01-09 11:54:51 +01:00
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_rng_shuffle_array(RNG *rng, void *data, uint elem_size_i, uint elem_num)
|
2005-07-20 03:33:44 +00:00
|
|
|
{
|
2022-03-30 17:26:42 +11:00
|
|
|
if (elem_num <= 1) {
|
2012-03-19 19:27:39 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-28 19:25:40 +10:00
|
|
|
const uint elem_size = elem_size_i;
|
2022-09-25 17:04:52 +10:00
|
|
|
uint i = elem_num;
|
2021-06-28 19:25:40 +10:00
|
|
|
void *temp = malloc(elem_size);
|
2005-07-20 03:33:44 +00:00
|
|
|
|
2014-04-02 10:09:48 +11:00
|
|
|
while (i--) {
|
2022-09-25 17:04:52 +10:00
|
|
|
const uint j = BLI_rng_get_uint(rng) % elem_num;
|
2012-05-12 15:02:10 +00:00
|
|
|
if (i != j) {
|
2022-09-25 17:04:52 +10:00
|
|
|
void *iElem = (uchar *)data + i * elem_size_i;
|
|
|
|
|
void *jElem = (uchar *)data + j * elem_size_i;
|
2014-03-30 13:12:33 +11:00
|
|
|
memcpy(temp, iElem, elem_size);
|
|
|
|
|
memcpy(iElem, jElem, elem_size);
|
|
|
|
|
memcpy(jElem, temp, elem_size);
|
2005-11-05 21:17:55 +00:00
|
|
|
}
|
2005-07-20 03:33:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(temp);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BLI_rng_shuffle_bitmap(RNG *rng, BLI_bitmap *bitmap, uint bits_num)
|
2021-06-28 19:25:40 +10:00
|
|
|
{
|
2022-03-30 17:26:42 +11:00
|
|
|
if (bits_num <= 1) {
|
2021-06-28 19:25:40 +10:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
uint i = bits_num;
|
2021-06-28 19:25:40 +10:00
|
|
|
while (i--) {
|
2022-09-25 17:04:52 +10:00
|
|
|
const uint j = BLI_rng_get_uint(rng) % bits_num;
|
2021-06-28 19:25:40 +10:00
|
|
|
if (i != j) {
|
|
|
|
|
const bool i_bit = BLI_BITMAP_TEST(bitmap, i);
|
|
|
|
|
const bool j_bit = BLI_BITMAP_TEST(bitmap, j);
|
|
|
|
|
BLI_BITMAP_SET(bitmap, i, j_bit);
|
|
|
|
|
BLI_BITMAP_SET(bitmap, j, i_bit);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
void BLI_rng_skip(RNG *rng, int n)
|
2007-12-04 13:57:28 +00:00
|
|
|
{
|
2022-09-25 18:33:28 +10:00
|
|
|
rng->rng.skip(uint(n));
|
2007-12-04 13:57:28 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-25 20:33:10 +00:00
|
|
|
/***/
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
float BLI_hash_frand(uint seed)
|
2011-12-17 00:52:36 +00:00
|
|
|
{
|
2013-09-01 15:31:09 +00:00
|
|
|
RNG rng;
|
2005-07-25 20:33:10 +00:00
|
|
|
|
2013-09-01 15:31:09 +00:00
|
|
|
BLI_rng_srandom(&rng, seed);
|
|
|
|
|
return BLI_rng_get_float(&rng);
|
2005-07-25 20:33:10 +00:00
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_array_randomize(void *data, uint elem_size, uint elem_num, uint seed)
|
2005-07-25 20:33:10 +00:00
|
|
|
{
|
|
|
|
|
RNG rng;
|
|
|
|
|
|
2012-10-23 13:50:44 +00:00
|
|
|
BLI_rng_seed(&rng, seed);
|
2022-03-30 17:26:42 +11:00
|
|
|
BLI_rng_shuffle_array(&rng, data, elem_size, elem_num);
|
2005-07-25 20:33:10 +00:00
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_bitmap_randomize(BLI_bitmap *bitmap, uint bits_num, uint seed)
|
2021-06-28 19:25:40 +10:00
|
|
|
{
|
|
|
|
|
RNG rng;
|
|
|
|
|
|
|
|
|
|
BLI_rng_seed(&rng, seed);
|
2022-03-30 17:26:42 +11:00
|
|
|
BLI_rng_shuffle_bitmap(&rng, bitmap, bits_num);
|
2021-06-28 19:25:40 +10:00
|
|
|
}
|
|
|
|
|
|
2005-08-25 13:11:04 +00:00
|
|
|
/* ********* for threaded random ************** */
|
|
|
|
|
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
struct RNG_THREAD_ARRAY {
|
2025-02-20 10:37:10 +01:00
|
|
|
std::array<RNG, BLENDER_MAX_THREADS> rng_tab;
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
};
|
|
|
|
|
|
2021-12-08 00:31:20 -05:00
|
|
|
RNG_THREAD_ARRAY *BLI_rng_threaded_new()
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
{
|
2022-09-25 17:04:52 +10:00
|
|
|
uint i;
|
2025-02-20 10:37:10 +01:00
|
|
|
RNG_THREAD_ARRAY *rngarr = MEM_new<RNG_THREAD_ARRAY>("random_array");
|
2018-06-17 16:32:54 +02:00
|
|
|
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
for (i = 0; i < BLENDER_MAX_THREADS; i++) {
|
2022-09-25 18:33:28 +10:00
|
|
|
BLI_rng_srandom(&rngarr->rng_tab[i], uint(clock()));
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
}
|
2018-06-17 16:32:54 +02:00
|
|
|
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
return rngarr;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BLI_rng_threaded_free(RNG_THREAD_ARRAY *rngarr)
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
{
|
2025-02-20 10:37:10 +01:00
|
|
|
MEM_delete(rngarr);
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread)
|
|
|
|
|
{
|
2025-02-20 10:37:10 +01:00
|
|
|
return BLI_rng_get_int(&rngarr->rng_tab[size_t(thread)]);
|
Fix T42139, vertical noise stripe patterns in noise texture.
Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).
First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.
Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.
Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.
Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.
2014-10-09 15:48:38 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-14 16:10:48 +11:00
|
|
|
/* ********* 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;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_halton_1d(uint prime, double offset, int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2022-09-25 18:33:28 +10:00
|
|
|
const double invprime = 1.0 / double(prime);
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2018-03-07 01:36:09 +01:00
|
|
|
*r = 0.0;
|
|
|
|
|
|
2017-11-14 16:10:48 +11:00
|
|
|
for (int s = 0; s < n; s++) {
|
|
|
|
|
*r = halton_ex(invprime, &offset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_halton_2d(const uint prime[2], double offset[2], int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
2022-09-25 18:33:28 +10:00
|
|
|
const double invprimes[2] = {1.0 / double(prime[0]), 1.0 / double(prime[1])};
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2018-03-07 01:36:09 +01:00
|
|
|
r[0] = r[1] = 0.0;
|
|
|
|
|
|
2017-11-14 16:10:48 +11:00
|
|
|
for (int s = 0; s < n; s++) {
|
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
|
r[i] = halton_ex(invprimes[i], &offset[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_halton_3d(const uint prime[3], double offset[3], int n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
|
|
|
|
const double invprimes[3] = {
|
2022-09-25 18:33:28 +10:00
|
|
|
1.0 / double(prime[0]), 1.0 / double(prime[1]), 1.0 / double(prime[2])};
|
2017-11-14 16:10:48 +11:00
|
|
|
|
2018-03-07 01:36:09 +01:00
|
|
|
r[0] = r[1] = r[2] = 0.0;
|
|
|
|
|
|
2017-11-14 16:10:48 +11:00
|
|
|
for (int s = 0; s < n; s++) {
|
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
|
r[i] = halton_ex(invprimes[i], &offset[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* From "Sampling with Hammersley and Halton Points" TT Wong
|
|
|
|
|
* Appendix: Source Code 1 */
|
2022-09-25 17:04:52 +10:00
|
|
|
BLI_INLINE double radical_inverse(uint n)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
|
|
|
|
double u = 0;
|
|
|
|
|
|
2020-07-10 11:41:14 +10:00
|
|
|
/* This reverse the bit-wise representation
|
2017-11-14 16:10:48 +11:00
|
|
|
* around the decimal point. */
|
|
|
|
|
for (double p = 0.5; n; p *= 0.5, n >>= 1) {
|
|
|
|
|
if (n & 1) {
|
|
|
|
|
u += p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return u;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-25 17:04:52 +10:00
|
|
|
void BLI_hammersley_1d(uint n, double *r)
|
2017-11-14 16:10:48 +11:00
|
|
|
{
|
|
|
|
|
*r = radical_inverse(n);
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-10 15:53:36 +02:00
|
|
|
namespace blender {
|
|
|
|
|
|
2024-01-19 11:57:57 +01:00
|
|
|
RandomNumberGenerator RandomNumberGenerator::from_random_seed()
|
|
|
|
|
{
|
2024-01-24 09:59:43 +01:00
|
|
|
std::random_device rd;
|
|
|
|
|
std::mt19937 e{rd()};
|
|
|
|
|
std::uniform_int_distribution<uint32_t> dist;
|
|
|
|
|
const uint32_t seed = dist(e);
|
|
|
|
|
return RandomNumberGenerator(seed);
|
2024-01-19 11:57:57 +01:00
|
|
|
}
|
|
|
|
|
|
2020-07-10 15:53:36 +02:00
|
|
|
void RandomNumberGenerator::seed_random(uint32_t seed)
|
|
|
|
|
{
|
|
|
|
|
this->seed(seed + hash[seed & 255]);
|
|
|
|
|
seed = this->get_uint32();
|
|
|
|
|
this->seed(seed + hash[seed & 255]);
|
|
|
|
|
seed = this->get_uint32();
|
|
|
|
|
this->seed(seed + hash[seed & 255]);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-17 12:48:41 +01:00
|
|
|
int RandomNumberGenerator::round_probabilistic(float x)
|
|
|
|
|
{
|
|
|
|
|
/* Support for negative values can be added when necessary. */
|
|
|
|
|
BLI_assert(x >= 0.0f);
|
|
|
|
|
const float round_up_probability = fractf(x);
|
|
|
|
|
const bool round_up = round_up_probability > this->get_float();
|
2022-09-25 18:33:28 +10:00
|
|
|
return int(x) + int(round_up);
|
2022-03-17 12:48:41 +01:00
|
|
|
}
|
|
|
|
|
|
2020-07-10 15:53:36 +02:00
|
|
|
float2 RandomNumberGenerator::get_unit_float2()
|
|
|
|
|
{
|
2022-09-25 18:33:28 +10:00
|
|
|
float a = float(M_PI * 2.0) * this->get_float();
|
2020-07-10 15:53:36 +02:00
|
|
|
return {cosf(a), sinf(a)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float3 RandomNumberGenerator::get_unit_float3()
|
|
|
|
|
{
|
|
|
|
|
float z = (2.0f * this->get_float()) - 1.0f;
|
|
|
|
|
float r = 1.0f - z * z;
|
|
|
|
|
if (r > 0.0f) {
|
2022-09-25 18:33:28 +10:00
|
|
|
float a = float(M_PI * 2.0) * this->get_float();
|
2020-07-10 15:53:36 +02:00
|
|
|
r = sqrtf(r);
|
|
|
|
|
float x = r * cosf(a);
|
|
|
|
|
float y = r * sinf(a);
|
|
|
|
|
return {x, y, z};
|
|
|
|
|
}
|
|
|
|
|
return {0.0f, 0.0f, 1.0f};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float2 RandomNumberGenerator::get_triangle_sample(float2 v1, float2 v2, float2 v3)
|
|
|
|
|
{
|
|
|
|
|
float u = this->get_float();
|
|
|
|
|
float v = this->get_float();
|
|
|
|
|
|
|
|
|
|
if (u + v > 1.0f) {
|
|
|
|
|
u = 1.0f - u;
|
|
|
|
|
v = 1.0f - v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float2 side_u = v2 - v1;
|
|
|
|
|
float2 side_v = v3 - v1;
|
|
|
|
|
|
|
|
|
|
float2 sample = v1;
|
|
|
|
|
sample += side_u * u;
|
|
|
|
|
sample += side_v * v;
|
|
|
|
|
return sample;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-02 13:25:25 +01:00
|
|
|
float3 RandomNumberGenerator::get_triangle_sample_3d(float3 v1, float3 v2, float3 v3)
|
|
|
|
|
{
|
|
|
|
|
float u = this->get_float();
|
|
|
|
|
float v = this->get_float();
|
|
|
|
|
|
|
|
|
|
if (u + v > 1.0f) {
|
|
|
|
|
u = 1.0f - u;
|
|
|
|
|
v = 1.0f - v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float3 side_u = v2 - v1;
|
|
|
|
|
float3 side_v = v3 - v1;
|
|
|
|
|
|
|
|
|
|
float3 sample = v1;
|
|
|
|
|
sample += side_u * u;
|
|
|
|
|
sample += side_v * v;
|
|
|
|
|
return sample;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-10 15:53:36 +02:00
|
|
|
void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
|
|
|
|
|
{
|
2020-07-20 12:16:20 +02:00
|
|
|
constexpr int64_t mask_bytes = 2;
|
2022-09-25 18:30:50 +10:00
|
|
|
constexpr int64_t rand_stride = int64_t(sizeof(x_)) - mask_bytes;
|
2020-07-10 15:53:36 +02:00
|
|
|
|
2020-07-20 12:16:20 +02:00
|
|
|
int64_t last_len = 0;
|
|
|
|
|
int64_t trim_len = r_bytes.size();
|
2020-07-10 15:53:36 +02:00
|
|
|
|
|
|
|
|
if (trim_len > rand_stride) {
|
|
|
|
|
last_len = trim_len % rand_stride;
|
|
|
|
|
trim_len = trim_len - last_len;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
trim_len = 0;
|
|
|
|
|
last_len = r_bytes.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *data_src = (const char *)&x_;
|
2020-07-20 12:16:20 +02:00
|
|
|
int64_t i = 0;
|
2020-07-10 15:53:36 +02:00
|
|
|
while (i != trim_len) {
|
|
|
|
|
BLI_assert(i < trim_len);
|
|
|
|
|
#ifdef __BIG_ENDIAN__
|
2020-07-20 12:16:20 +02:00
|
|
|
for (int64_t j = (rand_stride + mask_bytes) - 1; j != mask_bytes - 1; j--)
|
2020-07-10 15:53:36 +02:00
|
|
|
#else
|
2020-07-20 12:16:20 +02:00
|
|
|
for (int64_t j = 0; j != rand_stride; j++)
|
2020-07-10 15:53:36 +02:00
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
r_bytes[i++] = data_src[j];
|
|
|
|
|
}
|
|
|
|
|
this->step();
|
|
|
|
|
}
|
|
|
|
|
if (last_len) {
|
2020-07-20 12:16:20 +02:00
|
|
|
for (int64_t j = 0; j != last_len; j++) {
|
2020-07-10 15:53:36 +02:00
|
|
|
r_bytes[i++] = data_src[j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace blender
|