commit fbf93f7580f99b673a76692cda7e933128ec937a
parent f6c419b3c33984c897daf8c26e02af288c5d1bda
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 11 Jan 2019 14:43:00 +0100
Fix the s3d_scene_view_sample function
Diffstat:
1 file changed, 32 insertions(+), 9 deletions(-)
diff --git a/src/s3d_scene_view.c b/src/s3d_scene_view.c
@@ -1284,6 +1284,7 @@ s3d_scene_view_sample
struct geometry** pgeom;
struct geometry* geom;
size_t sz;
+ size_t i;
const struct fltui* fltui, *fltui_found;
const float* flt, *flt_found;
unsigned ishape;
@@ -1322,15 +1323,22 @@ s3d_scene_view_sample
} else {
fltui = darray_fltui_cdata_get(&scnview->cdf);
sz = darray_fltui_size_get(&scnview->cdf);
- f = u * fltui[sz-1].flt; /* Map u to the CDF bounds */
+ f = u * fltui[sz-1].flt; /* Map u to [0, SceneArea[ */
fltui_found = search_lower_bound
(&f, fltui, sz, sizeof(*fltui), cmp_float_to_fltui);
ASSERT(fltui_found);
+
+ /* search_lower_bound returns the first entry that is not less than `f'.
+ * The following code discards entries that are also `equal' to `f' */
+ i = (size_t)(fltui_found - fltui);
+ while(fltui[i].flt == f && i < sz) ++i;
+ ASSERT(i < sz);
+
+ fltui_found = fltui + i;
ishape = fltui_found->ui;
- /* Transform u to the geometry CDF bounds */
- if(fltui_found != fltui)
- f -= fltui_found[-1].flt;
+ /* Map f to [0, <Shape|Instance>Area[ */
+ if(i) f -= fltui_found[-1].flt;
}
pgeom = htable_geom_find(&scnview->cached_geoms, &ishape);
ASSERT(pgeom);
@@ -1353,12 +1361,19 @@ s3d_scene_view_sample
sz = darray_fltui_size_get(&geom->data.instance->scnview->cdf);
fltui_found = search_lower_bound
(&f, fltui, sz, sizeof(*fltui), cmp_float_to_fltui);
- ASSERT(fltui_found != NULL);
+ ASSERT(fltui_found);
+
+ /* search_lower_bound returns the first entry that is not less than `f'.
+ * The following code discards entries that are also `equal' to `f' */
+ i = (size_t)(fltui_found - fltui);
+ while(fltui[i].flt == f && i < sz) ++i;
+ ASSERT(i < sz);
+
+ fltui_found = fltui + i;
ishape = fltui_found->ui;
- /* Transform u to the geometry CDF bounds */
- if(fltui_found != fltui)
- f -= fltui_found[-1].flt;
+ /* Map `f' to [0, ShapeArea[ */
+ if(i) f -= fltui_found[-1].flt;
}
pgeom = htable_geom_find(&geom->data.instance->scnview->cached_geoms, &ishape);
ASSERT(pgeom);
@@ -1376,7 +1391,15 @@ s3d_scene_view_sample
sz = darray_float_size_get(&geom->data.mesh->cdf);
flt_found = search_lower_bound(&f, flt, sz, sizeof(*flt), cmp_float);
ASSERT(flt_found != NULL);
- primitive->prim_id = (unsigned)(flt_found - flt);
+ i = (size_t)(flt_found - flt);
+
+ /* search_lower_bound returns the first entry that is not less than `f'.
+ * The following code discards entries that are also `equal' to `f' */
+ while(flt[i] == f && i < sz) ++i;
+ ASSERT(i < sz);
+
+ primitive->prim_id = (unsigned)i;
+
} else {
FATAL("Unreachable code\n");
}