commit 0376c8923ecbbb65a456052cf190a8c46a2b2ad1
parent f8ab1ff43cc885e1276e3ddf55207788f44fe884
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 27 Jul 2016 16:32:14 +0200
Push further the session tests
Test multiple trace sessions on several scenes that have the same shapes.
Diffstat:
3 files changed, 291 insertions(+), 15 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -141,6 +141,7 @@ if(NOT NO_TEST)
new_test(test_s3d_primitive)
new_test(test_s3d_sampler)
new_test(test_s3d_scene)
+ new_test(test_s3d_session)
new_test(test_s3d_shape)
build_test(test_s3d_trace_ray)
diff --git a/src/test_s3d_scene.c b/src/test_s3d_scene.c
@@ -155,28 +155,13 @@ main(int argc, char** argv)
CHECK(s3d_scene_attach_shape(scn, shapes[0]), RES_OK);
- CHECK(s3d_session_create(NULL, 0, NULL), RES_BAD_ARG);
- CHECK(s3d_session_create(scn, 0, NULL), RES_BAD_ARG);
- CHECK(s3d_session_create(NULL, S3D_TRACE, NULL), RES_BAD_ARG);
- CHECK(s3d_session_create(scn, S3D_TRACE, NULL), RES_BAD_ARG);
- CHECK(s3d_session_create(NULL, 0, &session), RES_BAD_ARG);
- CHECK(s3d_session_create(scn, 0, &session), RES_BAD_ARG);
- CHECK(s3d_session_create(NULL, S3D_TRACE, &session), RES_BAD_ARG);
CHECK(s3d_session_create(scn, S3D_TRACE, &session), RES_OK);
-
- CHECK(s3d_session_get_mask(NULL, NULL), RES_BAD_ARG);
- CHECK(s3d_session_get_mask(session, NULL), RES_BAD_ARG);
- CHECK(s3d_session_get_mask(NULL, &mask), RES_BAD_ARG);
CHECK(s3d_session_get_mask(session, &mask), RES_OK);
CHECK(mask, S3D_TRACE);
CHECK(s3d_scene_detach_shape(scn, shapes[0]), RES_OK);
CHECK(s3d_scene_clear(scn), RES_OK);
- CHECK(s3d_session_ref_get(NULL), RES_BAD_ARG);
- CHECK(s3d_session_ref_get(session), RES_OK);
- CHECK(s3d_session_ref_put(NULL), RES_BAD_ARG);
- CHECK(s3d_session_ref_put(session), RES_OK);
CHECK(s3d_session_ref_put(session), RES_OK);
CHECK(s3d_session_create(scn, S3D_TRACE, &session), RES_OK);
diff --git a/src/test_s3d_session.c b/src/test_s3d_session.c
@@ -0,0 +1,290 @@
+/* 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/float3.h>
+#include <rsys/float2.h>
+
+struct mesh_context {
+ const float* verts;
+ const unsigned* ids;
+};
+
+/*******************************************************************************
+ * Cube data
+ ******************************************************************************/
+static const float cube_verts[] = {
+ 0.f, 0.f, 0.f,
+ 1.f, 0.f, 0.f,
+ 0.f, 1.f, 0.f,
+ 1.f, 1.f, 0.f,
+ 0.f, 0.f, 1.f,
+ 1.f, 0.f, 1.f,
+ 0.f, 1.f, 1.f,
+ 1.f, 1.f, 1.f
+};
+static const unsigned cube_nverts = sizeof(cube_verts) / sizeof(float[3]);
+
+/* Front faces are CW. The normals point into the cube */
+static const unsigned cube_ids[] = {
+ 0, 2, 1, 1, 2, 3, /* Front */
+ 0, 4, 2, 2, 4, 6, /* Left */
+ 4, 5, 6, 6, 5, 7, /* Back */
+ 3, 7, 1, 1, 7, 5, /* Right */
+ 2, 6, 3, 3, 6, 7, /* Top */
+ 0, 1, 4, 4, 1, 5 /* Bottom */
+};
+static const unsigned cube_ntris = sizeof(cube_ids) / sizeof(unsigned[3]);
+
+/*******************************************************************************
+ * Plane data
+ ******************************************************************************/
+static const float plane_verts[] = {
+ 0.f, 0.f, 0.5f,
+ 1.f, 0.f, 0.5f,
+ 1.f, 1.f, 0.5f,
+ 0.f, 1.f, 0.5f
+};
+static const unsigned plane_nverts = sizeof(plane_verts) / sizeof(float[3]);
+
+static const unsigned plane_ids[] = { 0, 1, 2, 2, 3, 0 };
+static const unsigned plane_ntris = sizeof(plane_ids) / sizeof(unsigned[3]);
+
+/*******************************************************************************
+ * helper function
+ ******************************************************************************/
+static void
+get_ids(const unsigned itri, unsigned ids[3], void* data)
+{
+ const unsigned id = itri * 3;
+ const struct mesh_context* ctx = data;
+ NCHECK(ctx, NULL);
+ NCHECK(ids, NULL);
+ ids[0] = ctx->ids[id + 0];
+ ids[1] = ctx->ids[id + 1];
+ ids[2] = ctx->ids[id + 2];
+}
+
+static void
+get_pos(const unsigned ivert, float pos[3], void* data)
+{
+ const unsigned i = ivert*3;
+ const struct mesh_context* ctx = data;
+ NCHECK(ctx, NULL);
+ NCHECK(pos, NULL);
+ pos[0] = ctx->verts[i + 0];
+ pos[1] = ctx->verts[i + 1];
+ pos[2] = ctx->verts[i + 2];
+}
+
+/*******************************************************************************
+ * Main test function
+ ******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct mesh_context ctx;
+ struct s3d_device* dev;
+ struct s3d_hit hit, hit2;
+ struct s3d_scene* scn;
+ struct s3d_scene* scn2;
+ struct s3d_session* session;
+ struct s3d_session* session2;
+ struct s3d_shape* cube;
+ struct s3d_shape* plane;
+ struct s3d_vertex_data vdata;
+ float org[3], dir[3], range[2];
+ unsigned icube;
+ unsigned iplane;
+ int mask;
+ (void)argc, (void)argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(s3d_device_create(NULL, &allocator, 1, &dev), RES_OK);
+ CHECK(s3d_scene_create(dev, &scn), RES_OK);
+ CHECK(s3d_scene_create(dev, &scn2), RES_OK);
+
+ vdata.type = S3D_FLOAT3;
+ vdata.usage = S3D_POSITION;
+ vdata.get = get_pos;
+
+ ctx.ids = cube_ids;
+ ctx.verts = cube_verts;
+ CHECK(s3d_shape_create_mesh(dev, &cube), RES_OK);
+ CHECK(s3d_shape_get_id(cube, &icube), RES_OK);
+ CHECK(s3d_mesh_setup_indexed_vertices
+ (cube, cube_ntris, get_ids, cube_nverts, &vdata, 1, &ctx), RES_OK);
+
+ ctx.ids = plane_ids;
+ ctx.verts = plane_verts;
+ CHECK(s3d_shape_create_mesh(dev, &plane), RES_OK);
+ CHECK(s3d_shape_get_id(plane, &iplane), RES_OK);
+ CHECK(s3d_mesh_setup_indexed_vertices
+ (plane, plane_ntris, get_ids, plane_nverts, &vdata, 1, &ctx), RES_OK);
+
+ CHECK(s3d_scene_attach_shape(scn, cube), RES_OK);
+ CHECK(s3d_scene_attach_shape(scn, plane), RES_OK);
+
+ CHECK(s3d_session_create(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(s3d_session_create(scn, 0, NULL), RES_BAD_ARG);
+ CHECK(s3d_session_create(NULL, S3D_SAMPLE, NULL), RES_BAD_ARG);
+ CHECK(s3d_session_create(scn, S3D_SAMPLE, NULL), RES_BAD_ARG);
+ CHECK(s3d_session_create(NULL, 0, &session), RES_BAD_ARG);
+ CHECK(s3d_session_create(scn, 0, &session), RES_BAD_ARG);
+ CHECK(s3d_session_create(NULL, S3D_SAMPLE, &session), RES_BAD_ARG);
+ CHECK(s3d_session_create(scn, S3D_SAMPLE, &session), RES_OK);
+
+ CHECK(s3d_session_get_mask(NULL, NULL), RES_BAD_ARG);
+ CHECK(s3d_session_get_mask(session, NULL), RES_BAD_ARG);
+ CHECK(s3d_session_get_mask(NULL, &mask), RES_BAD_ARG);
+ CHECK(s3d_session_get_mask(session, &mask), RES_OK);
+ CHECK(mask, S3D_SAMPLE);
+
+ CHECK(s3d_session_ref_get(NULL), RES_BAD_ARG);
+ CHECK(s3d_session_ref_get(session), RES_OK);
+ CHECK(s3d_session_ref_put(NULL), RES_BAD_ARG);
+ CHECK(s3d_session_ref_put(session), RES_OK);
+ CHECK(s3d_session_ref_put(session), RES_OK);
+
+ CHECK(s3d_session_create(scn, S3D_TRACE|S3D_GET_PRIMITIVE, &session), RES_OK);
+ CHECK(s3d_session_get_mask(session, &mask), RES_OK);
+ CHECK(mask & S3D_TRACE, S3D_TRACE);
+ CHECK(mask & S3D_GET_PRIMITIVE, S3D_GET_PRIMITIVE);
+ CHECK(s3d_session_ref_put(session), RES_OK);
+
+ CHECK(s3d_session_create(scn, S3D_SAMPLE|S3D_GET_PRIMITIVE, &session), RES_OK);
+ CHECK(s3d_session_get_mask(session, &mask), RES_OK);
+ CHECK(mask & S3D_SAMPLE, S3D_SAMPLE);
+ CHECK(mask & S3D_GET_PRIMITIVE, S3D_GET_PRIMITIVE);
+
+ f3(org, 0.5f, 0.25f, 0.25f);
+ f3(dir, 0.f, 0.f, 1.f);
+ f2(range, 0.f, FLT_MAX);
+ CHECK(s3d_session_trace_ray(session, org, dir, range, NULL, &hit), RES_BAD_OP);
+
+ CHECK(s3d_session_create(scn, S3D_TRACE, &session2), RES_OK);
+ CHECK(s3d_session_trace_ray(session2, org, dir, range, NULL, &hit), RES_OK);
+ CHECK(S3D_HIT_NONE(&hit), 0);
+ CHECK(hit.prim.inst_id, S3D_INVALID_ID);
+ CHECK(hit.prim.geom_id, iplane);
+ CHECK(hit.prim.prim_id, 0);
+
+ f3_minus(dir, dir);
+ CHECK(s3d_session_trace_ray(session2, org, dir, range, NULL, &hit), RES_OK);
+ CHECK(S3D_HIT_NONE(&hit), 0);
+ CHECK(hit.prim.inst_id, S3D_INVALID_ID);
+ CHECK(hit.prim.geom_id, icube);
+ CHECK(hit.prim.prim_id, 0);
+
+ CHECK(s3d_shape_enable(plane, 0), RES_OK);
+ CHECK(s3d_session_ref_put(session), RES_OK);
+ CHECK(s3d_session_create(scn, S3D_TRACE, &session), RES_OK);
+
+ f3_minus(dir, dir);
+ CHECK(s3d_session_trace_ray(session2, org, dir, range, NULL, &hit), RES_OK);
+ CHECK(S3D_HIT_NONE(&hit), 0);
+ CHECK(hit.prim.inst_id, S3D_INVALID_ID);
+ CHECK(hit.prim.geom_id, iplane);
+ CHECK(hit.prim.prim_id, 0);
+
+ CHECK(s3d_session_trace_ray(session, org, dir, range, NULL, &hit), RES_OK);
+ CHECK(S3D_HIT_NONE(&hit), 0);
+ CHECK(hit.prim.inst_id, S3D_INVALID_ID);
+ CHECK(hit.prim.geom_id, icube);
+ CHECK(hit.prim.prim_id, 4);
+
+ CHECK(s3d_session_ref_put(session), RES_OK);
+ CHECK(s3d_session_ref_put(session2), RES_OK);
+ CHECK(s3d_shape_enable(plane, 1), RES_OK);
+
+ CHECK(s3d_scene_attach_shape(scn2, cube), RES_OK);
+ CHECK(s3d_scene_attach_shape(scn2, plane), RES_OK);
+
+ CHECK(s3d_session_create(scn, S3D_TRACE, &session), RES_OK);
+ CHECK(s3d_session_create(scn2, S3D_TRACE, &session2), RES_OK);
+
+ CHECK(s3d_session_trace_ray(session, org, dir, range, NULL, &hit), RES_OK);
+ CHECK(s3d_session_trace_ray(session2, org, dir, range, NULL, &hit2), RES_OK);
+ CHECK(f3_eq(hit.normal, hit2.normal), 1);
+ CHECK(f2_eq(hit.uv, hit2.uv), 1);
+ CHECK(hit.distance, hit2.distance);
+ CHECK(S3D_PRIMITIVE_EQ(&hit.prim, &hit2.prim), 1);
+ CHECK(hit.prim.inst_id, S3D_INVALID_ID);
+ CHECK(hit.prim.geom_id, iplane);
+ CHECK(hit.prim.prim_id, 0);
+
+ CHECK(s3d_scene_detach_shape(scn2, plane), RES_OK);
+ CHECK(s3d_session_trace_ray(session2, org, dir, range, NULL, &hit2), RES_OK);
+ CHECK(f3_eq(hit.normal, hit2.normal), 1);
+ CHECK(f2_eq(hit.uv, hit2.uv), 1);
+ CHECK(hit.distance, hit2.distance);
+ CHECK(S3D_PRIMITIVE_EQ(&hit.prim, &hit2.prim), 1);
+
+ CHECK(s3d_session_ref_put(session), RES_OK);
+ CHECK(s3d_session_ref_put(session2), RES_OK);
+
+ CHECK(s3d_session_create(scn, S3D_TRACE, &session), RES_OK);
+ CHECK(s3d_session_create(scn2, S3D_TRACE, &session2), RES_OK);
+
+ CHECK(s3d_session_trace_ray(session, org, dir, range, NULL, &hit), RES_OK);
+ CHECK(f3_eq(hit.normal, hit2.normal), 1);
+ CHECK(f2_eq(hit.uv, hit2.uv), 1);
+ CHECK(hit.distance, hit2.distance);
+ CHECK(S3D_PRIMITIVE_EQ(&hit.prim, &hit2.prim), 1);
+ CHECK(hit.prim.inst_id, S3D_INVALID_ID);
+ CHECK(hit.prim.geom_id, iplane);
+ CHECK(hit.prim.prim_id, 0);
+
+ CHECK(s3d_session_trace_ray(session2, org, dir, range, NULL, &hit2), RES_OK);
+ CHECK(hit2.prim.inst_id, S3D_INVALID_ID);
+ CHECK(hit2.prim.geom_id, icube);
+ CHECK(hit2.prim.prim_id, 4);
+
+ CHECK(s3d_session_ref_put(session), RES_OK);
+ CHECK(s3d_session_ref_put(session2), RES_OK);
+
+ CHECK(s3d_shape_ref_put(cube), RES_OK);
+ CHECK(s3d_shape_ref_put(plane), RES_OK);
+ CHECK(s3d_scene_ref_put(scn), RES_OK);
+ CHECK(s3d_scene_ref_put(scn2), 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;
+}
+