commit 13cb9531e4b16d1e442dcb3dc6e799fa477b072c
parent 3e81de4b5b8021567606bafc289f8235ef52486f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 13 Nov 2019 11:35:05 +0100
Fix the s3d_scene_view_compute_area function
The returned area was wrong when the scene view was created with the
S3D_SAMPLE flag. In such situation, this function internally queries the
unormalized cumulative of the primitive areas which was assumed to be
computed from the primitive area multiplied by two. The overall area
fetches from this cumulative was thus divided by two before being
returned to the caller.
Since the version 0.6.1 this cumulative directly accumulates
the primitive area, without this factor 2. However, the
s3d_scene_view_compute_area function still relies on the previous
assumption. This commit fixes this issue.
Diffstat:
3 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/s3d_scene_view.c b/src/s3d_scene_view.c
@@ -1577,13 +1577,12 @@ s3d_scene_view_compute_area(struct s3d_scene_view* scnview, float* out_area)
}
if((scnview->mask & S3D_SAMPLE) != 0) {
/* Retrieve the overall scene area from the scene cumulative distribution
- * function. Note that the CDF stores the cumulative triangle area
- * multiplied by 2; the real scene area is thus the CDF upper bound / 2 */
+ * function */
size_t len = darray_fltui_size_get(&scnview->cdf);
if(!len) {
area = 0.f;
} else {
- area = darray_fltui_cdata_get(&scnview->cdf)[len - 1].flt * 0.5f;
+ area = darray_fltui_cdata_get(&scnview->cdf)[len - 1].flt;
}
} else {
struct htable_geom_iterator it, end;
diff --git a/src/s3d_scene_view_c.h b/src/s3d_scene_view_c.h
@@ -74,7 +74,7 @@ struct s3d_scene_view {
struct list_node node; /* Attachment point to the scene scene_views pool */
struct htable_geom cached_geoms; /* Cached shape geometries */
- struct darray_fltui cdf; /* Unormalized CDF */
+ struct darray_fltui cdf; /* Unormalized cumulative of the primitive areas */
struct darray_nprims_cdf nprims_cdf;
/* Map an instantiated scene to its scene view */
diff --git a/src/test_s3d_scene_view.c b/src/test_s3d_scene_view.c
@@ -131,6 +131,8 @@ test_miscellaneous
{
struct s3d_scene* scn;
struct s3d_scene_view* scnview;
+ float V;
+ float A;
int mask;
CHK(s3d_scene_create(dev, &scn) == RES_OK);
@@ -142,7 +144,6 @@ test_miscellaneous
CHK(s3d_scene_view_create(NULL, S3D_SAMPLE, NULL) == RES_BAD_ARG);
CHK(s3d_scene_view_create(scn, S3D_SAMPLE, NULL) == RES_BAD_ARG);
CHK(s3d_scene_view_create(NULL, 0, &scnview) == RES_BAD_ARG);
- CHK(s3d_scene_view_create(scn, 0, &scnview) == RES_BAD_ARG);
CHK(s3d_scene_view_create(NULL, S3D_SAMPLE, &scnview) == RES_BAD_ARG);
CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &scnview) == RES_OK);
@@ -170,6 +171,23 @@ test_miscellaneous
CHK((mask & S3D_GET_PRIMITIVE) == S3D_GET_PRIMITIVE);
CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
+ CHK(s3d_scene_detach_shape(scn, plane) == RES_OK);
+ CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK);
+ CHK(s3d_scene_view_get_mask(scnview, &mask) == RES_OK);
+ CHK(mask == S3D_TRACE);
+ CHK(s3d_scene_view_compute_volume(scnview, &V) == RES_OK);
+ CHK(s3d_scene_view_compute_area(scnview, &A) == RES_OK);
+ CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
+ CHK(eq_eps(A, 6.f, 1.e-6f));
+ CHK(eq_eps(V, 1.f, 1.e-6f));
+
+ CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &scnview) == RES_OK);
+ CHK(s3d_scene_view_compute_volume(scnview, &V) == RES_OK);
+ CHK(s3d_scene_view_compute_area(scnview, &A) == RES_OK);
+ CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
+ CHK(eq_eps(A, 6.f, 1.e-6f));
+ CHK(eq_eps(V, 1.f, 1.e-6f));
+
CHK(s3d_scene_ref_put(scn) == RES_OK);
}