star-2d

Contour structuring for efficient 2D geometric queries
git clone git://git.meso-star.fr/star-2d.git
Log | Files | Refs | README | LICENSE

commit fc58b3484b6ca26a1a55f67a3ba0a04996ae3d64
parent 47e30a4173e993dfb22839f993feda0351795e80
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 12 Jan 2018 11:22:42 +0100

Fix the "sample" function

Diffstat:
Asrc/test_s2d_scene_view.c | 402+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 402 insertions(+), 0 deletions(-)

diff --git a/src/test_s2d_scene_view.c b/src/test_s2d_scene_view.c @@ -0,0 +1,402 @@ +/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com) + * + * 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 "s2d.h" +#include "test_s2d_utils.h" + +#include <rsys/float2.h> + +#include <string.h> + +static void +test_miscellaneous + (struct s2d_device* dev, + struct s2d_shape* square, + struct s2d_shape* line) +{ + struct s2d_scene* scn; + struct s2d_scene_view* scnview; + int mask; + + CHK(s2d_scene_create(dev, &scn) == RES_OK); + CHK(s2d_scene_attach_shape(scn, square) == RES_OK); + CHK(s2d_scene_attach_shape(scn, line) == RES_OK); + + CHK(s2d_scene_view_create(NULL, 0, NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_create(scn, 0, NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_create(NULL, S2D_SAMPLE, NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_create(scn, S2D_SAMPLE, NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_create(NULL, 0, &scnview) == RES_BAD_ARG); + CHK(s2d_scene_view_create(scn, 0, &scnview) == RES_BAD_ARG); + CHK(s2d_scene_view_create(NULL, S2D_SAMPLE, &scnview) == RES_BAD_ARG); + CHK(s2d_scene_view_create(scn, S2D_SAMPLE, &scnview) == RES_OK); + + CHK(s2d_scene_view_get_mask(NULL, NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_get_mask(scnview, NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_get_mask(NULL, &mask) == RES_BAD_ARG); + CHK(s2d_scene_view_get_mask(scnview, &mask) == RES_OK); + CHK(mask == S2D_SAMPLE); + + CHK(s2d_scene_view_ref_get(NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_ref_get(scnview) == RES_OK); + CHK(s2d_scene_view_ref_put(NULL) == RES_BAD_ARG); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_TRACE|S2D_GET_PRIMITIVE, &scnview) == RES_OK); + CHK(s2d_scene_view_get_mask(scnview, &mask) == RES_OK); + CHK((mask & S2D_TRACE) == S2D_TRACE); + CHK((mask & S2D_GET_PRIMITIVE) == S2D_GET_PRIMITIVE); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_SAMPLE|S2D_GET_PRIMITIVE, &scnview) == RES_OK); + CHK(s2d_scene_view_get_mask(scnview, &mask) == RES_OK); + CHK((mask & S2D_SAMPLE) == S2D_SAMPLE); + CHK((mask & S2D_GET_PRIMITIVE) == S2D_GET_PRIMITIVE); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + + CHK(s2d_scene_ref_put(scn) == RES_OK); +} + +static void +test_trace_ray + (struct s2d_device* dev, + struct s2d_shape* square, + struct s2d_shape* line) +{ + struct s2d_scene* scn; + struct s2d_scene* scn2; + struct s2d_scene_view* scnview; + struct s2d_scene_view* scnview2; + struct s2d_hit hit, hit2; + float org[2], dir[2], range[2]; + unsigned isquare; + unsigned iline; + + CHK(s2d_shape_get_id(square, &isquare) == RES_OK); + CHK(s2d_shape_get_id(line, &iline) == RES_OK); + + CHK(s2d_scene_create(dev, &scn) == RES_OK); + CHK(s2d_scene_create(dev, &scn2) == RES_OK); + CHK(s2d_scene_attach_shape(scn, line) == RES_OK); + CHK(s2d_scene_attach_shape(scn, square) == RES_OK); + CHK(s2d_scene_attach_shape(scn2, square) == RES_OK); + CHK(s2d_scene_attach_shape(scn2, line) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_SAMPLE|S2D_GET_PRIMITIVE, &scnview) == RES_OK); + + f2(org, 0.f, -0.25f); + f2(dir, 0.f, 1.f); + f2(range, 0.f, FLT_MAX); + CHK(s2d_scene_view_trace_ray(scnview, org, dir, range, NULL, &hit) == RES_BAD_OP); + + CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview2) == RES_OK); + CHK(s2d_scene_view_trace_ray(scnview2, org, dir, range, NULL, &hit) == RES_OK); + CHK(S2D_HIT_NONE(&hit) == 0); + CHK(hit.prim.geom_id == iline); + CHK(hit.prim.prim_id == 0); + + f2(dir, 0.f, -1.f); + CHK(s2d_scene_view_trace_ray(scnview2, org, dir, range, NULL, &hit) == RES_OK); + CHK(S2D_HIT_NONE(&hit) == 0); + CHK(hit.prim.geom_id == isquare); + CHK(hit.prim.prim_id == 0); + f2(dir, 0.f, 1.f); + + CHK(s2d_shape_enable(line, 0) == RES_OK); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK); + + CHK(s2d_scene_view_trace_ray(scnview2, org, dir, range, NULL, &hit) == RES_OK); + CHK(S2D_HIT_NONE(&hit) == 0); + CHK(hit.prim.geom_id == iline); + CHK(hit.prim.prim_id == 0); + + CHK(s2d_scene_view_trace_ray(scnview, org, dir, range, NULL, &hit) == RES_OK); + CHK(S2D_HIT_NONE(&hit) == 0); + CHK(hit.prim.geom_id == isquare); + CHK(hit.prim.prim_id == 2); + + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_view_ref_put(scnview2) == RES_OK); + CHK(s2d_shape_enable(line, 1) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK); + CHK(s2d_scene_view_create(scn2, S2D_TRACE, &scnview2) == RES_OK); + + CHK(s2d_scene_view_trace_ray(scnview, org, dir, range, NULL, &hit) == RES_OK); + CHK(s2d_scene_view_trace_ray(scnview2, org, dir, range, NULL, &hit2) == RES_OK); + CHK(f2_eq(hit.normal, hit2.normal)); + CHK(hit.u == hit2.u); + CHK(hit.distance == hit2.distance); + CHK(S2D_PRIMITIVE_EQ(&hit.prim, &hit2.prim) == 1); + CHK(hit.prim.geom_id == iline); + CHK(hit.prim.prim_id == 0); + + CHK(s2d_scene_detach_shape(scn2, line) == RES_OK); + CHK(s2d_scene_view_trace_ray(scnview2, org, dir, range, NULL, &hit2) == RES_OK); + CHK(f2_eq(hit.normal, hit2.normal)); + CHK(hit.u == hit2.u); + CHK(hit.distance == hit2.distance); + CHK(S2D_PRIMITIVE_EQ(&hit.prim, &hit2.prim) == 1); + + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_view_ref_put(scnview2) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK); + CHK(s2d_scene_view_create(scn2, S2D_TRACE, &scnview2) == RES_OK); + + CHK(s2d_scene_view_trace_ray(scnview, org, dir, range, NULL, &hit) == RES_OK); + CHK(f2_eq(hit.normal, hit2.normal)); + CHK(hit.u == hit2.u); + CHK(hit.distance == hit2.distance); + CHK(S2D_PRIMITIVE_EQ(&hit.prim, &hit2.prim) == 1); + CHK(hit.prim.geom_id == iline); + CHK(hit.prim.prim_id == 0); + + CHK(s2d_scene_view_trace_ray(scnview2, org, dir, range, NULL, &hit2) == RES_OK); + CHK(hit2.prim.geom_id == isquare); + CHK(hit2.prim.prim_id == 2); + + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_view_ref_put(scnview2) == RES_OK); + + CHK(s2d_scene_ref_put(scn) == RES_OK); + CHK(s2d_scene_ref_put(scn2) == RES_OK); +} + +static void +test_sample + (struct s2d_device* dev, + struct s2d_shape* square, + struct s2d_shape* line) +{ + #define NSAMPS 512 + struct s2d_scene* scn; + struct s2d_scene_view* scnview; + struct s2d_primitive prims[NSAMPS]; + float u, v, s; + unsigned isquare; + unsigned iline; + int nsamps_square; + int nsamps_line; + int i; + + CHK(s2d_scene_create(dev, &scn) == RES_OK); + CHK(s2d_scene_attach_shape(scn, square) == RES_OK); + CHK(s2d_scene_attach_shape(scn, line) == RES_OK); + CHK(s2d_shape_get_id(square, &isquare) == RES_OK); + CHK(s2d_shape_get_id(line, &iline) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK); + CHK(s2d_scene_view_sample(scnview, 0.f, 0.f, &prims[0], &s) == RES_BAD_OP); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_SAMPLE, &scnview) == RES_OK); + CHK(s2d_scene_view_sample(scnview, 0.f, 0.f, &prims[0], &s) == RES_OK); + CHK(prims[0].geom_id == isquare || prims[0].geom_id == iline); + + nsamps_square = 0; + nsamps_line = 0; + srand(0); + FOR_EACH(i, 0, NSAMPS) { + u = rand_canonic(), v = rand_canonic(); + CHK(s2d_scene_view_sample(scnview, u, v, &prims[i], &s) == RES_OK); + if(prims[i].geom_id == isquare) { + ++nsamps_square; + } else { + CHK(prims[i].geom_id == iline); + ++nsamps_line; + } + } + CHK(nsamps_square != 0); + CHK(nsamps_line != 0); + + CHK(s2d_shape_enable(square, 0) == RES_OK); + srand(0); + FOR_EACH(i, 0, NSAMPS) { + struct s2d_primitive prim; + u = rand_canonic(), v = rand_canonic(); + CHK(s2d_scene_view_sample(scnview, u, v, &prim, &s) == RES_OK); + CHK(S2D_PRIMITIVE_EQ(&prim, &prims[i]) == 1); + } + + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_view_create(scn, S2D_SAMPLE, &scnview) == RES_OK); + + srand(0); + FOR_EACH(i, 0, NSAMPS) { + u = rand_canonic(), v = rand_canonic(); + CHK(s2d_scene_view_sample(scnview, u, v, &prims[i], &s) == RES_OK); + CHK(prims[i].geom_id == iline); + } + + CHK(s2d_shape_enable(square, 1) == RES_OK); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_ref_put(scn) == RES_OK); +} + +static void +test_get_primitive + (struct s2d_device* dev, + struct s2d_shape* square, + struct s2d_shape* line) +{ + struct s2d_scene* scn; + struct s2d_scene_view* scnview; + struct s2d_primitive prim; + size_t nprims; + unsigned i; + unsigned isquare; + unsigned iline; + int square_prims[4]; + int line_prims; + + CHK(s2d_scene_create(dev, &scn) == RES_OK); + CHK(s2d_scene_attach_shape(scn, square) == RES_OK); + CHK(s2d_scene_attach_shape(scn, line) == RES_OK); + CHK(s2d_shape_get_id(square, &isquare) == RES_OK); + CHK(s2d_shape_get_id(line, &iline) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK); + CHK(s2d_scene_view_get_primitive(scnview, 0, &prim) == RES_BAD_OP); + CHK(s2d_scene_view_primitives_count(scnview, &nprims) == RES_OK); + CHK(nprims == 5); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + + CHK(s2d_scene_view_create(scn, S2D_GET_PRIMITIVE, &scnview) == RES_OK); + CHK(s2d_scene_view_primitives_count(scnview, &nprims) == RES_OK); + CHK(nprims == 5); + + memset(square_prims, 0, sizeof(square_prims)); + line_prims = 0; + FOR_EACH(i, 0, nprims) { + CHK(s2d_scene_view_get_primitive(scnview, i, &prim) == RES_OK); + CHK(prim.scene_prim_id == i); + if(prim.geom_id == isquare) { + square_prims[prim.prim_id] = 1; + } else { + CHK(prim.geom_id == iline); + line_prims = 1; + } + } + FOR_EACH(i, 0, 4) CHK(square_prims[i]); + CHK(line_prims); + + CHK(s2d_scene_detach_shape(scn, square) == RES_OK); + CHK(s2d_scene_view_primitives_count(scnview, &nprims) == RES_OK); + CHK(nprims == 5); + memset(square_prims, 0, sizeof(square_prims)); + line_prims = 0; + FOR_EACH(i, 0, nprims) { + CHK(s2d_scene_view_get_primitive(scnview, i, &prim) == RES_OK); + CHK(prim.scene_prim_id == i); + if(prim.geom_id == isquare) { + square_prims[prim.prim_id] = 1; + } else { + CHK(prim.geom_id == iline); + line_prims = 1; + } + } + FOR_EACH(i, 0, 4) CHK(square_prims[i]); + CHK(line_prims); + + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_view_create(scn, S2D_GET_PRIMITIVE, &scnview) == RES_OK); + CHK(s2d_scene_view_primitives_count(scnview, &nprims) == RES_OK); + CHK(nprims == 1); + line_prims = 0; + CHK(s2d_scene_view_get_primitive(scnview, 0, &prim) == RES_OK); + CHK(prim.scene_prim_id == 0); + CHK(prim.geom_id == iline); + + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_attach_shape(scn, square) == RES_OK); + CHK(s2d_shape_enable(line, 0) == RES_OK); + CHK(s2d_scene_view_create(scn, S2D_GET_PRIMITIVE, &scnview) == RES_OK); + CHK(s2d_scene_view_primitives_count(scnview, &nprims) == RES_OK); + CHK(nprims == 4); + memset(square_prims, 0, sizeof(square_prims)); + FOR_EACH(i, 0, nprims) { + CHK(s2d_scene_view_get_primitive(scnview, i, &prim) == RES_OK); + CHK(prim.scene_prim_id == i); + CHK(prim.geom_id == isquare); + square_prims[prim.prim_id] = 1; + } + FOR_EACH(i, 0, 4) CHK(square_prims[i]); + + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); + CHK(s2d_scene_ref_put(scn) == RES_OK); +} + +/******************************************************************************* + * Main test function + ******************************************************************************/ +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct s2d_device* dev; + struct s2d_shape* square; + struct s2d_shape* line; + struct s2d_vertex_data vdata; + (void)argc, (void)argv; + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + + CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK); + + vdata.type = S2D_FLOAT2; + vdata.usage = S2D_POSITION; + vdata.get = line_segments_get_position; + + CHK(s2d_shape_create_line_segments(dev, &square) == RES_OK); + CHK(s2d_line_segments_setup_indexed_vertices(square, square_nsegs, + line_segments_get_ids, square_nverts, &vdata, 1, (void*)&square_desc) + == RES_OK); + + CHK(s2d_shape_create_line_segments(dev, &line) == RES_OK); + CHK(s2d_line_segments_setup_indexed_vertices(line, line_nsegs, + line_segments_get_ids, line_nverts, &vdata, 1, (void*)&line_desc) + == RES_OK); + + test_miscellaneous(dev, square, line); + test_trace_ray(dev, square, line); + test_sample(dev, square, line); + test_get_primitive(dev, square, line); + + CHK(s2d_shape_ref_put(square) == RES_OK); + CHK(s2d_shape_ref_put(line) == RES_OK); + CHK(s2d_device_ref_put(dev) == RES_OK); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHK(mem_allocated_size() == 0); + return 0; +} +