BLI: add probabilistic rounding utility
This commit is contained in:
parent
8f68cff01b
commit
d0968a9c52
|
@ -103,6 +103,12 @@ class RandomNumberGenerator {
|
|||
return float3(rand1, rand2, 1.0f - rand1 - rand2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Round value to the next integer randomly.
|
||||
* 4.9f is more likely to round to 5 than 4.6f.
|
||||
*/
|
||||
int round_probabilistic(float x);
|
||||
|
||||
float2 get_unit_float2();
|
||||
float3 get_unit_float3();
|
||||
/**
|
||||
|
|
|
@ -374,6 +374,15 @@ void RandomNumberGenerator::seed_random(uint32_t seed)
|
|||
this->seed(seed + hash[seed & 255]);
|
||||
}
|
||||
|
||||
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();
|
||||
return (int)x + (int)round_up;
|
||||
}
|
||||
|
||||
float2 RandomNumberGenerator::get_unit_float2()
|
||||
{
|
||||
float a = (float)(M_PI * 2.0) * this->get_float();
|
||||
|
|
|
@ -378,13 +378,6 @@ class AddOperation : public CurvesSculptStrokeOperation {
|
|||
return kdtree;
|
||||
}
|
||||
|
||||
int float_to_int_amount(float amount_f, RandomNumberGenerator &rng)
|
||||
{
|
||||
const float add_probability = fractf(amount_f);
|
||||
const bool add_point = add_probability > rng.get_float();
|
||||
return (int)amount_f + (int)add_point;
|
||||
}
|
||||
|
||||
bool is_too_close_to_existing_point(const float3 position, const float minimum_distance) const
|
||||
{
|
||||
if (old_kdtree_ == nullptr) {
|
||||
|
@ -439,7 +432,7 @@ class AddOperation : public CurvesSculptStrokeOperation {
|
|||
* the triangle directly. If the triangle is larger than the brush, distribute new points
|
||||
* in a circle on the triangle plane. */
|
||||
if (looptri_area < area_threshold) {
|
||||
const int amount = this->float_to_int_amount(looptri_area * density, looptri_rng);
|
||||
const int amount = looptri_rng.round_probabilistic(looptri_area * density);
|
||||
|
||||
threading::parallel_for(IndexRange(amount), 512, [&](const IndexRange amount_range) {
|
||||
RandomNumberGenerator point_rng{rng_base_seed + looptri_index * 1000 +
|
||||
|
@ -476,7 +469,7 @@ class AddOperation : public CurvesSculptStrokeOperation {
|
|||
const float radius_proj = std::sqrt(radius_proj_sq);
|
||||
const float circle_area = M_PI * radius_proj_sq;
|
||||
|
||||
const int amount = this->float_to_int_amount(circle_area * density, rng);
|
||||
const int amount = rng.round_probabilistic(circle_area * density);
|
||||
|
||||
const float3 axis_1 = math::normalize(v1 - v0) * radius_proj;
|
||||
const float3 axis_2 = math::normalize(
|
||||
|
|
|
@ -114,10 +114,8 @@ static void sample_mesh_surface(const Mesh &mesh,
|
|||
const int looptri_seed = noise::hash(looptri_index, seed);
|
||||
RandomNumberGenerator looptri_rng(looptri_seed);
|
||||
|
||||
const float points_amount_fl = area * base_density * looptri_density_factor;
|
||||
const float add_point_probability = fractf(points_amount_fl);
|
||||
const bool add_point = add_point_probability > looptri_rng.get_float();
|
||||
const int point_amount = (int)points_amount_fl + (int)add_point;
|
||||
const int point_amount = looptri_rng.round_probabilistic(area * base_density *
|
||||
looptri_density_factor);
|
||||
|
||||
for (int i = 0; i < point_amount; i++) {
|
||||
const float3 bary_coord = looptri_rng.get_barycentric_coordinates();
|
||||
|
|
Loading…
Reference in New Issue