star-3d

Surface structuring for efficient 3D geometric queries
git clone git://git.meso-star.fr/star-3d.git
Log | Files | Refs | README | LICENSE

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:
Msrc/s3d_scene_view.c | 41++++++++++++++++++++++++++++++++---------
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"); }