commit dd78aa8092fffb9940cdad6ea87604500242a5dd
parent 53086f69c549aac9101683b280f55267f446b5a5
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 1 Jul 2016 10:20:06 +0200
Fix an issue in the setup of the shape filter function
If only the filter function was updated between 2 scene sessions, the
filter function was not committed to the Embree library and consequently
it was not up to date.
Diffstat:
2 files changed, 53 insertions(+), 20 deletions(-)
diff --git a/src/s3d_scene.c b/src/s3d_scene.c
@@ -167,6 +167,29 @@ scene_geometry_flush_enable_state
scn->is_rtc_scn_outdated = 1;
}
+static INLINE void
+scene_geometry_flush_filter_function
+ (struct s3d_scene* scn,
+ struct geometry* geom, /* Cached geometry */
+ const struct s3d_shape* shape)
+{
+ ASSERT(scn && geom && shape && geom->irtc != RTC_INVALID_GEOMETRY_ID);
+ ASSERT(shape->type == GEOM_MESH);
+
+ if(geom->data.mesh->filter.func == shape->data.mesh->filter.func
+ && geom->data.mesh->filter.data == shape->data.mesh->filter.data)
+ return; /* Up to date */
+
+ geom->data.mesh->filter = shape->data.mesh->filter;
+ if(!geom->data.mesh->filter.func) {
+ rtcSetIntersectionFilterFunction(scn->rtc_scn, geom->irtc, NULL);
+ } else {
+ rtcSetIntersectionFilterFunction(scn->rtc_scn, geom->irtc, filter_wrapper);
+ rtcSetUserData(scn->rtc_scn, geom->irtc, &geom->data.mesh->filter);
+ }
+ scn->is_rtc_scn_outdated = 1;
+}
+
static res_T
scene_register_embree_geometry(struct s3d_scene* scn, struct geometry* geom)
{
@@ -204,6 +227,28 @@ scene_register_embree_geometry(struct s3d_scene* scn, struct geometry* geom)
return RES_OK;
}
+static INLINE void
+scene_geometry_flush_positions(struct s3d_scene* scn, struct geometry* geom)
+{
+ ASSERT(scn && geom && geom->type == GEOM_MESH);
+ ASSERT(geom->irtc != RTC_INVALID_GEOMETRY_ID);
+ rtcSetBuffer(scn->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER,
+ mesh_get_pos(geom->data.mesh), 0, sizeof(float[3]));
+ rtcUpdateBuffer(scn->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER);
+ scn->is_rtc_scn_outdated = 1;
+}
+
+static INLINE void
+scene_geometry_flush_indices(struct s3d_scene* scn, struct geometry* geom)
+{
+ ASSERT(scn && geom && geom->type == GEOM_MESH);
+ ASSERT(geom->irtc != RTC_INVALID_GEOMETRY_ID);
+ rtcSetBuffer(scn->rtc_scn, geom->irtc, RTC_INDEX_BUFFER,
+ mesh_get_ids(geom->data.mesh), 0, sizeof(uint32_t[3]));
+ rtcUpdateBuffer(scn->rtc_scn, geom->irtc, RTC_INDEX_BUFFER);
+ scn->is_rtc_scn_outdated = 1;
+}
+
static void
scene_session_clear(struct s3d_scene* scn)
{
@@ -306,31 +351,20 @@ scene_register_mesh
scn->is_rtc_scn_outdated = 1;
}
- /* Update the cached mesh states */
- geom->flip_surface = shape->flip_surface;
- geom->data.mesh->filter = shape->data.mesh->filter;
-
res = scene_register_embree_geometry(scn, geom);
if(res != RES_OK) goto error;
if(upd_pos) { /* Update the Embree vertex buffer if necessary */
- rtcSetBuffer(scn->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER,
- mesh_get_pos(geom->data.mesh), 0, sizeof(float[3]));
- rtcUpdateBuffer(scn->rtc_scn, geom->irtc, RTC_VERTEX_BUFFER);
- scn->is_rtc_scn_outdated = 1;
+ scene_geometry_flush_positions(scn, geom);
}
if(upd_ids) { /* Update the Embree index buffer if necessary */
- rtcSetBuffer(scn->rtc_scn, geom->irtc, RTC_INDEX_BUFFER,
- mesh_get_ids(geom->data.mesh), 0, sizeof(uint32_t[3]));
- rtcUpdateBuffer(scn->rtc_scn, geom->irtc, RTC_INDEX_BUFFER);
- scn->is_rtc_scn_outdated = 1;
- }
- if(geom->data.mesh->filter.func) { /* Upd the filter func of the mesh */
- rtcSetIntersectionFilterFunction(scn->rtc_scn, geom->irtc, filter_wrapper);
- rtcSetUserData(scn->rtc_scn, geom->irtc, &geom->data.mesh->filter);
+ scene_geometry_flush_indices(scn, geom);
}
+ /* Flush the remaining geometry states */
scene_geometry_flush_enable_state(scn, geom, shape);
+ scene_geometry_flush_filter_function(scn, geom, shape);
+ geom->flip_surface = shape->flip_surface;
/* Flush the shape mesh states */
shape->data.mesh->resize_mask = 0;
@@ -918,7 +952,7 @@ s3d_scene_trace_ray
hit_setup(scn, &ray_ex, hit);
- return RES_OK;
+ return RES_OK;
}
res_T
@@ -1214,7 +1248,7 @@ s3d_scene_compute_area(struct s3d_scene* scn, float* area)
if((scn->session_mask & S3D_SAMPLE) != 0) {
/* Retrieve the overall scene area from the scene cumulative distribution
- * function. Note that the CDF stores the cumulateive triangle area
+ * function. Note that the CDF stores the cumulative triangle area
* multiplied by 2; the real scene area is thus the CDF upper bound / 2 */
size_t len = darray_fltui_size_get(&scn->cdf);
if(!len) {
diff --git a/src/s3d_shape.c b/src/s3d_shape.c
@@ -105,11 +105,10 @@ error:
shape = NULL;
}
goto exit;
-
}
/*******************************************************************************
- * Exported s3d_shape functions:
+ * Exported s3d_shape functions
******************************************************************************/
res_T
s3d_shape_create_mesh