commit 21d12e901b3176357819bb80633e2ae39865506c
parent 8c02a0ac03afd8f5241c0a66e62cdf582b78b5ef
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 29 Aug 2016 15:08:17 +0200
Fix the update of the embree scene
If a scene contained untransformed instances only, then the Embree scene
was not updated.
Diffstat:
5 files changed, 156 insertions(+), 6 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -144,6 +144,7 @@ if(NOT NO_TEST)
new_test(test_s3d_scene)
new_test(test_s3d_scene_view)
new_test(test_s3d_shape)
+ new_test(test_s3d_trace_ray_instance)
build_test(test_s3d_trace_ray)
register_test(test_s3d_trace_ray_legacy test_s3d_trace_ray)
diff --git a/src/s3d.h b/src/s3d.h
@@ -243,8 +243,8 @@ s3d_scene_instantiate
(struct s3d_scene* scn,
struct s3d_shape** shape);
-/* Attach the shape to the scene.
- * On success, the scene gets a reference onto the attached shape */
+/* Attach the shape to the scene. On success, the scene gets a reference onto
+ * the attached shape */
S3D_API res_T
s3d_scene_attach_shape
(struct s3d_scene* scn,
diff --git a/src/s3d_scene_view.c b/src/s3d_scene_view.c
@@ -77,7 +77,7 @@ scene_view_destroy_geometry(struct s3d_scene_view* scnview, struct geometry* geo
if(geom->irtc != RTC_INVALID_GEOMETRY_ID) {
rtcDeleteGeometry(scnview->rtc_scn, geom->irtc);
geom->irtc = RTC_INVALID_GEOMETRY_ID;
- scnview->rtc_delete_geometry = 1; /* Notify the scene upd */
+ scnview->rtc_scn_update = 1; /* Notify the scene upd */
}
geometry_ref_put(geom);
}
@@ -228,6 +228,8 @@ embree_geometry_register
}
if(geom->irtc == RTC_INVALID_GEOMETRY_ID)
return RES_UNKNOWN_ERR;
+
+ scnview->rtc_scn_update = 1;
}
/* Register the embree geometry in the embree2geoms associative array */
@@ -310,7 +312,7 @@ static INLINE res_T
scene_view_setup_embree(struct s3d_scene_view* scnview)
{
struct htable_geom_iterator it, end;
- int rtc_outdated = scnview->rtc_delete_geometry;
+ int rtc_outdated = 0;
res_T res = RES_OK;
ASSERT(scnview);
@@ -345,10 +347,12 @@ scene_view_setup_embree(struct s3d_scene_view* scnview)
geom->embree_outdated_mask = 0;
}
+ rtc_outdated = rtc_outdated || scnview->rtc_scn_update;
+
/* Commit the embree changes */
if(rtc_outdated) {
rtcCommit(scnview->rtc_scn);
- scnview->rtc_delete_geometry = 0;
+ scnview->rtc_scn_update = 0;
}
exit:
diff --git a/src/s3d_scene_view_c.h b/src/s3d_scene_view_c.h
@@ -96,7 +96,7 @@ struct s3d_scene_view {
scene_shape_cb_T on_shape_detach_cb;
int mask; /* Combinatin of enum s3d_scene_view_flag */
- int rtc_delete_geometry; /* Define if Embree geometries were deleted */
+ int rtc_scn_update; /* Define if Embree geometries were deleted/added */
RTCScene rtc_scn; /* Embree scene */
ref_T ref;
diff --git a/src/test_s3d_trace_ray_instance.c b/src/test_s3d_trace_ray_instance.c
@@ -0,0 +1,145 @@
+/* Copyright (C) |Meso|Star> 2015-2016 (contact@meso-star.com)
+ *
+ * This software is a computer program whose purpose is to describe a
+ * virtual 3D environment that can be ray-traced and sampled both robustly
+ * and efficiently.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms. */
+
+#include "s3d.h"
+#include "test_s3d_utils.h"
+
+#include <rsys/float2.h>
+#include <rsys/float3.h>
+
+static const float quad_verts[] = {
+ -1.f, -1.f, 0.f,
+ -1.f, 1.f, 0.f,
+ 1.f, 1.f, 0.f,
+ 1.f, -1.f, 0.f
+};
+static const unsigned quad_nverts = sizeof(quad_verts)/sizeof(float[3]);
+static const unsigned quad_ids[] = { 0, 1, 3, 3, 2, 1 };
+static const unsigned quad_ntris = sizeof(quad_ids)/sizeof(unsigned[3]);
+
+static void
+quad_get_ids(const unsigned itri, unsigned ids[3], void* data)
+{
+ const unsigned id = itri * 3;
+ NCHECK(ids, NULL);
+ CHECK(itri < quad_ntris, 1);
+ (void)data;
+ ids[0] = quad_ids[id + 0];
+ ids[1] = quad_ids[id + 1];
+ ids[2] = quad_ids[id + 2];
+}
+
+static void
+quad_get_pos(const unsigned ivert, float pos[3], void* data)
+{
+ const unsigned i = ivert*3;
+ NCHECK(pos, NULL);
+ CHECK(ivert < quad_nverts, 1);
+ (void)data;
+ pos[0] = quad_verts[i+0];
+ pos[1] = quad_verts[i+1];
+ pos[2] = quad_verts[i+2];
+}
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct s3d_device* dev;
+ struct s3d_hit hit[2];
+ struct s3d_scene* scn;
+ struct s3d_scene_view* view[2];
+ struct s3d_shape* quad;
+ struct s3d_shape* quad_inst;
+ struct s3d_vertex_data vdata;
+ unsigned quad_id;
+ unsigned quad_inst_id;
+ float org[3];
+ float dir[3];
+ float range[2];
+ (void)argc, (void)argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+ CHECK(s3d_device_create(NULL, &allocator, 1, &dev), RES_OK);
+
+ vdata.type = S3D_FLOAT3;
+ vdata.usage = S3D_POSITION;
+ vdata.get = quad_get_pos;
+ CHECK(s3d_shape_create_mesh(dev, &quad), RES_OK);
+ CHECK(s3d_mesh_setup_indexed_vertices
+ (quad, quad_ntris, quad_get_ids, quad_nverts, &vdata, 1, NULL), RES_OK);
+
+ CHECK(s3d_scene_create(dev, &scn), RES_OK);
+ CHECK(s3d_scene_attach_shape(scn, quad), RES_OK);
+ CHECK(s3d_scene_instantiate(scn, &quad_inst), RES_OK);
+ CHECK(s3d_scene_ref_put(scn), RES_OK);
+
+ CHECK(s3d_scene_create(dev, &scn), RES_OK);
+ CHECK(s3d_scene_attach_shape(scn, quad_inst), RES_OK);
+ CHECK(s3d_scene_view_create(scn, S3D_TRACE, &view[0]), RES_OK);
+
+ CHECK(s3d_scene_clear(scn), RES_OK);
+ CHECK(s3d_scene_attach_shape(scn, quad), RES_OK);
+ CHECK(s3d_scene_view_create(scn, S3D_TRACE, &view[1]), RES_OK);
+
+ CHECK(s3d_shape_get_id(quad, &quad_id), RES_OK);
+ CHECK(s3d_shape_get_id(quad_inst, &quad_inst_id), RES_OK);
+
+ f3(org, 0.f, 0.5f, -1.f);
+ f3(dir, 0.f, 0.f, 1.f);
+ f2(range, 0.f, FLT_MAX);
+ CHECK(s3d_scene_view_trace_ray(view[0], org, dir, range, NULL, &hit[0]), RES_OK);
+ CHECK(s3d_scene_view_trace_ray(view[1], org, dir, range, NULL, &hit[1]), RES_OK);
+
+ CHECK(hit[0].prim.prim_id, 1);
+ CHECK(hit[1].prim.prim_id, 1);
+ CHECK(hit[0].prim.geom_id, quad_id);
+ CHECK(hit[1].prim.geom_id, quad_id);
+ CHECK(hit[0].prim.inst_id, quad_inst_id);
+ CHECK(hit[1].prim.inst_id, S3D_INVALID_ID);
+ CHECK(f3_eq_eps(hit[0].normal, hit[1].normal, 1.e-6f), 1);
+ CHECK(f2_eq_eps(hit[0].uv, hit[1].uv, 1.e-6f), 1);
+ CHECK(eq_epsf(hit[0].distance, hit[1].distance, 1.e-6f), 1);
+
+ CHECK(s3d_scene_view_ref_put(view[0]), RES_OK);
+ CHECK(s3d_scene_view_ref_put(view[1]), RES_OK);
+
+ CHECK(s3d_shape_ref_put(quad_inst), RES_OK);
+ CHECK(s3d_shape_ref_put(quad), RES_OK);
+ CHECK(s3d_scene_ref_put(scn), RES_OK);
+ CHECK(s3d_device_ref_put(dev), RES_OK);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}