[Bf-blender-cvs] [0d4fa234148] strand_editmode: Use a consistent number of RNG steps in both sample generation and skipping.
Lukas Tönne
noreply at git.blender.org
Mon Aug 21 07:47:00 CEST 2017
Commit: 0d4fa2341488870c1f4847c7b5e3063212dfe226
Author: Lukas Tönne
Date: Mon Aug 21 06:42:59 2017 +0100
Branches: strand_editmode
https://developer.blender.org/rB0d4fa2341488870c1f4847c7b5e3063212dfe226
Use a consistent number of RNG steps in both sample generation and skipping.
This is to ensure that threaded generator usage creates the exact same results
as the non-threaded base version. Further improvements and testing will be
needed.
===================================================================
M source/blender/blenkernel/intern/mesh_sample.c
===================================================================
diff --git a/source/blender/blenkernel/intern/mesh_sample.c b/source/blender/blenkernel/intern/mesh_sample.c
index f0c91e5d465..f3224d7467e 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -371,7 +371,8 @@ static void generator_random_free(MSurfaceSampleGenerator_Random *gen)
static void* generator_random_thread_context_create(const MSurfaceSampleGenerator_Random *gen, int start)
{
RNG *rng = BLI_rng_new(gen->seed);
- BLI_rng_skip(rng, start);
+ // 3 RNG gets per sample
+ BLI_rng_skip(rng, start * 3);
return rng;
}
@@ -664,7 +665,8 @@ static void generator_volume_random_free(MVolumeSampleGenerator_Random *gen)
static void *generator_volume_random_thread_context_create(MVolumeSampleGenerator_Random *gen, int start)
{
RNG *rng = BLI_rng_new(gen->seed);
- BLI_rng_skip(rng, start);
+ // 11 RNG gets per sample
+ BLI_rng_skip(rng, start * 11);
return rng;
}
@@ -704,47 +706,23 @@ static void generator_volume_ray_cb(void *userdata, int index, const BVHTreeRay
}
}
-static void generator_volume_random_cast_ray(MVolumeSampleGenerator_Random *gen, void *thread_ctx)
+typedef struct Ray {
+ float start[3];
+ float end[3];
+} Ray;
+
+static void generator_volume_random_cast_ray(MVolumeSampleGenerator_Random *gen, const Ray* ray)
{
- /* bounding box margin to get clean ray intersections */
- static const float margin = 0.01f;
-
- RNG *rng = thread_ctx;
- float ray_start[3], ray_end[3], ray_dir[3];
- int axis;
-
- ray_start[0] = BLI_rng_get_float(rng);
- ray_start[1] = BLI_rng_get_float(rng);
- ray_start[2] = 0.0f;
- ray_end[0] = BLI_rng_get_float(rng);
- ray_end[1] = BLI_rng_get_float(rng);
- ray_end[2] = 1.0f;
-
- axis = BLI_rng_get_int(rng) % 3;
- switch (axis) {
- case 0: break;
- case 1:
- SHIFT3(float, ray_start[0], ray_start[1], ray_start[2]);
- SHIFT3(float, ray_end[0], ray_end[1], ray_end[2]);
- break;
- case 2:
- SHIFT3(float, ray_start[2], ray_start[1], ray_start[0]);
- SHIFT3(float, ray_end[2], ray_end[1], ray_end[0]);
- break;
- }
+ Ray wray;
+ float dir[3];
- mul_v3_fl(ray_start, 1.0f + 2.0f*margin);
- add_v3_fl(ray_start, -margin);
- mul_v3_fl(ray_end, 1.0f + 2.0f*margin);
- add_v3_fl(ray_end, -margin);
+ madd_v3_v3v3v3(wray.start, gen->min, ray->start, gen->extent);
+ madd_v3_v3v3v3(wray.end, gen->min, ray->end, gen->extent);
- madd_v3_v3v3v3(ray_start, gen->min, ray_start, gen->extent);
- madd_v3_v3v3v3(ray_end, gen->min, ray_end, gen->extent);
-
- sub_v3_v3v3(ray_dir, ray_end, ray_start);
+ sub_v3_v3v3(dir, wray.end, wray.start);
gen->tothits = 0;
- BLI_bvhtree_ray_cast_all(gen->bvhdata.tree, ray_start, ray_dir, 0.0f, BVH_RAYCAST_DIST_MAX,
+ BLI_bvhtree_ray_cast_all(gen->bvhdata.tree, wray.start, dir, 0.0f, BVH_RAYCAST_DIST_MAX,
generator_volume_ray_cb, gen);
gen->cur_seg = 0;
@@ -766,13 +744,49 @@ static void generator_volume_init_segment(MVolumeSampleGenerator_Random *gen)
gen->cur_sample = 0;
}
+static void generator_volume_get_ray(RNG *rng, Ray *ray)
+{
+ /* bounding box margin to get clean ray intersections */
+ static const float margin = 0.01f;
+
+ ray->start[0] = BLI_rng_get_float(rng);
+ ray->start[1] = BLI_rng_get_float(rng);
+ ray->start[2] = 0.0f;
+ ray->end[0] = BLI_rng_get_float(rng);
+ ray->end[1] = BLI_rng_get_float(rng);
+ ray->end[2] = 1.0f;
+
+ int axis = BLI_rng_get_int(rng) % 3;
+ switch (axis) {
+ case 0: break;
+ case 1:
+ SHIFT3(float, ray->start[0], ray->start[1], ray->start[2]);
+ SHIFT3(float, ray->end[0], ray->end[1], ray->end[2]);
+ break;
+ case 2:
+ SHIFT3(float, ray->start[2], ray->start[1], ray->start[0]);
+ SHIFT3(float, ray->end[2], ray->end[1], ray->end[0]);
+ break;
+ }
+
+ mul_v3_fl(ray->start, 1.0f + 2.0f*margin);
+ add_v3_fl(ray->start, -margin);
+ mul_v3_fl(ray->end, 1.0f + 2.0f*margin);
+ add_v3_fl(ray->end, -margin);
+}
+
static bool generator_volume_random_make_sample(MVolumeSampleGenerator_Random *gen, void *thread_ctx, MeshSample *sample)
{
RNG *rng = thread_ctx;
- BVHTreeRayHit *a, *b;
+
+ Ray ray1, ray2;
+ // Do all RNG gets at the beggining for keeping consistent state
+ generator_volume_get_ray(rng, &ray1);
+ generator_volume_get_ray(rng, &ray2);
+ float t = BLI_rng_get_float(rng);
if (gen->cur_seg + 1 >= gen->tothits) {
- generator_volume_random_cast_ray(gen, thread_ctx);
+ generator_volume_random_cast_ray(gen, &ray1);
if (gen->tothits < 2)
return false;
}
@@ -781,24 +795,22 @@ static bool generator_volume_random_make_sample(MVolumeSampleGenerator_Random *g
gen->cur_seg += 2;
if (gen->cur_seg + 1 >= gen->tothits) {
- generator_volume_random_cast_ray(gen, thread_ctx);
+ generator_volume_random_cast_ray(gen, &ray2);
if (gen->tothits < 2)
return false;
}
generator_volume_init_segment(gen);
}
- a = &gen->ray_hits[gen->cur_seg];
- b = &gen->ray_hits[gen->cur_seg + 1];
+ BVHTreeRayHit *a = &gen->ray_hits[gen->cur_seg];
+ BVHTreeRayHit *b = &gen->ray_hits[gen->cur_seg + 1];
if (gen->cur_sample < gen->cur_tot) {
- float t;
sample->orig_verts[0] = 0;
sample->orig_verts[1] = 0;
sample->orig_verts[2] = 0;
- t = BLI_rng_get_float(rng);
interp_v3_v3v3(sample->orig_weights, a->co, b->co, t);
gen->cur_sample += 1;
More information about the Bf-blender-cvs
mailing list