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 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:
Mcmake/CMakeLists.txt | 1+
Msrc/test_s3d_scene.c | 15---------------
Asrc/test_s3d_session.c | 290+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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; +} +