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 83ec660c02f1f7f925c2e17abfac7e15c7cf634b
parent bdc9d040617eb14b891abfb5b2816a1f8cc70236
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 18 Jan 2018 15:58:03 +0100

Test the sampling of scene view with a spherical shape

Diffstat:
Mcmake/CMakeLists.txt | 5+++--
Msrc/s3d_primitive.c | 18++++++++----------
Msrc/test_s3d_primitive.c | 8--------
Asrc/test_s3d_sample_sphere.c | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_s3d_sampler.c | 8--------
Msrc/test_s3d_scene_view.c | 8--------
Msrc/test_s3d_trace_ray_sphere.c | 10++++++++++
Msrc/test_s3d_utils.h | 8++++++++
8 files changed, 171 insertions(+), 36 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -142,15 +142,16 @@ if(NOT NO_TEST) endfunction() new_test(test_s3d_device) - new_test(test_s3d_primitive) new_test(test_s3d_sampler) + new_test(test_s3d_sample_sphere) new_test(test_s3d_scene) new_test(test_s3d_scene_view) + new_test(test_s3d_seams) new_test(test_s3d_shape) new_test(test_s3d_sphere) + new_test(test_s3d_primitive) new_test(test_s3d_trace_ray_instance) new_test(test_s3d_trace_ray_sphere) - new_test(test_s3d_seams) build_test(test_s3d_trace_ray) register_test(test_s3d_trace_ray_legacy test_s3d_trace_ray) diff --git a/src/s3d_primitive.c b/src/s3d_primitive.c @@ -58,7 +58,13 @@ mesh_get_primitive_attrib ASSERT(geom && geom->type == GEOM_MESH && prim && prim->shape__ == geom); ASSERT(uv && attrib); + /* Unormalized barycentric coordinates */ w = CLAMP(1.f - uv[0] - uv[1], 0.f, 1.f); + if(uv[0] < 0.f || uv[1] < 0.f || uv[0] > 1.f || uv[1] > 1.f + || !eq_epsf(w + uv[0] + uv[1], 1.f, 1.e-3f)) { + res = RES_BAD_ARG; + goto error; + } /* The mesh haven't the required mesh attrib */ if(usage != S3D_GEOMETRY_NORMAL && !geom->data.mesh->attribs[usage]) { @@ -146,11 +152,11 @@ sphere_get_attrib double phi, cos_theta, sin_theta; float P[3]; float N[3]; - ASSERT(geom && geom->type == GEOM_MESH && prim && prim->shape__ == geom); + ASSERT(geom && geom->type == GEOM_SPHERE && prim && prim->shape__ == geom); ASSERT(uv && attrib); /* Only position and geometry normal are valid sphere attribs */ - if(usage != S3D_GEOMETRY_NORMAL || usage != S3D_POSITION) { + if(usage != S3D_GEOMETRY_NORMAL && usage != S3D_POSITION) { res = RES_BAD_ARG; goto error; } @@ -221,14 +227,6 @@ s3d_primitive_get_attrib goto error; } - /* Unormalized barycentric coordinates */ - w = CLAMP(1.f - uv[0] - uv[1], 0.f, 1.f); - if(uv[0] < 0.f || uv[1] < 0.f || uv[0] > 1.f || uv[1] > 1.f - || !eq_epsf(w + uv[0] + uv[1], 1.f, 1.e-3f)) { - res = RES_BAD_ARG; - goto error; - } - if(prim->inst__ == NULL) { geom_shape = (struct geometry*)prim->shape__; flip_surface = geom_shape->flip_surface; diff --git a/src/test_s3d_primitive.c b/src/test_s3d_primitive.c @@ -49,14 +49,6 @@ 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]); -static float -rand_canonic(void) -{ - int r; - while((r = rand()) == RAND_MAX); - return (float)r / (float)RAND_MAX; -} - static void plane_get_ids(const unsigned itri, unsigned ids[3], void* data) { diff --git a/src/test_s3d_sample_sphere.c b/src/test_s3d_sample_sphere.c @@ -0,0 +1,142 @@ +/* Copyright (C) |Meso|Star> 2015-2018 (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> + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct s3d_attrib attr0; + struct s3d_attrib attr1; + struct s3d_primitive prim0; + struct s3d_primitive prim1; + struct s3d_device* dev; + struct s3d_shape* sphere0; + struct s3d_shape* sphere1; + struct s3d_scene* scn; + struct s3d_scene_view* view; + unsigned sphere0_id; + unsigned sphere1_id; + float center[3]; + float st0[2]; + float st1[2]; + int N = 10000; + int i; + float sum; + float E, V, SE; + (void)argc, (void)argv; + + CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); + CHK(s3d_device_create(NULL, &allocator, 0, &dev) == RES_OK); + CHK(s3d_scene_create(dev, &scn) == RES_OK); + + CHK(s3d_shape_create_sphere(dev, &sphere0) == RES_OK); + CHK(s3d_shape_create_sphere(dev, &sphere1) == RES_OK); + CHK(s3d_shape_get_id(sphere0, &sphere0_id) == RES_OK); + CHK(s3d_shape_get_id(sphere1, &sphere1_id) == RES_OK); + + CHK(s3d_sphere_setup(sphere0, f3(center,-1.5, 0, 0), 2) == RES_OK); + CHK(s3d_sphere_setup(sphere1, f3(center, 1.5, 0, 0), 2) == RES_OK); + CHK(s3d_scene_attach_shape(scn, sphere0) == RES_OK); + CHK(s3d_scene_attach_shape(scn, sphere1) == RES_OK); + + CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &view) == RES_OK); + CHK(s3d_scene_view_sample(view, 0, 0, 0, &prim0, st0) == RES_OK); + CHK(prim0.prim_id == 0); + CHK(prim0.geom_id == sphere0_id || prim0.geom_id == sphere1_id); + CHK(prim0.inst_id == S3D_INVALID_ID); + + CHK(s3d_scene_view_sample(view, 0, 0, 0, &prim1, st1) == RES_OK); + CHK(S3D_PRIMITIVE_EQ(&prim0, &prim1)); + CHK(f2_eq(st0, st1)); + + CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_0, st0, &attr0) == RES_BAD_ARG); + CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_1, st0, &attr0) == RES_BAD_ARG); + CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_2, st0, &attr0) == RES_BAD_ARG); + CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_3, st0, &attr0) == RES_BAD_ARG); + CHK(s3d_primitive_get_attrib(&prim0, S3D_POSITION, st0, &attr0) == RES_OK); + CHK(s3d_primitive_get_attrib + (&prim0, S3D_GEOMETRY_NORMAL, st0, &attr1) == RES_OK); + + if(prim0.geom_id == sphere0_id) { + f3_sub(attr0.value, attr0.value, f3(center,-1.5, 0, 0)); + } else { + f3_sub(attr0.value, attr0.value, f3(center, 1.5, 0, 0)); + } + f3_mulf(attr1.value, attr1.value, 2.f); + CHK(f3_eq_eps(attr0.value, attr1.value, 1.e-3f)); + + /* Check that 50 percents of samples lie onto "sphere0" */ + FOR_EACH(i, 0, N) { + const float u = rand_canonic(); + const float v = rand_canonic(); + const float w = rand_canonic(); + + CHK(s3d_scene_view_sample(view, u, v, w, &prim0, st0) == RES_OK); + if(prim0.geom_id == sphere0_id) { + sum += 1; + } + + CHK(s3d_primitive_get_attrib(&prim0, S3D_POSITION, st0, &attr0) == RES_OK); + CHK(s3d_primitive_get_attrib + (&prim0, S3D_GEOMETRY_NORMAL, st0, &attr1) == RES_OK); + + if(prim0.geom_id == sphere0_id) { + f3_sub(attr0.value, attr0.value, f3(center,-1.5, 0, 0)); + } else { + f3_sub(attr0.value, attr0.value, f3(center, 1.5, 0, 0)); + } + f3_mulf(attr1.value, attr1.value, 2.f); + CHK(f3_eq_eps(attr0.value, attr1.value, 1.e-3f)); + } + E = sum / (float)N; + V = sum / (float)N - E*E; + SE = (float)sqrt(V/(float)N); + CHK(eq_epsf(E, 0.5, SE)); + + CHK(s3d_device_ref_put(dev) == RES_OK); + CHK(s3d_scene_ref_put(scn) == RES_OK); + CHK(s3d_shape_ref_put(sphere0) == RES_OK); + CHK(s3d_shape_ref_put(sphere1) == RES_OK); + CHK(s3d_scene_view_ref_put(view) == RES_OK); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHK(mem_allocated_size() == 0); + return 0; +} + diff --git a/src/test_s3d_sampler.c b/src/test_s3d_sampler.c @@ -38,14 +38,6 @@ #define NSAMPS 4096 -static float -rand_canonic(void) -{ - int r; - while((r = rand()) == RAND_MAX); - return (float)r / (float)RAND_MAX; -} - int main(int argc, char** argv) { diff --git a/src/test_s3d_scene_view.c b/src/test_s3d_scene_view.c @@ -99,14 +99,6 @@ static const unsigned plane_ntris = sizeof(plane_ids) / sizeof(unsigned[3]); /******************************************************************************* * helper function ******************************************************************************/ -static float -rand_canonic(void) -{ - int r; - while((r = rand()) == RAND_MAX); - return (float)r / (float)RAND_MAX; -} - static void get_ids(const unsigned itri, unsigned ids[3], void* data) { diff --git a/src/test_s3d_trace_ray_sphere.c b/src/test_s3d_trace_ray_sphere.c @@ -94,13 +94,23 @@ main(int argc, char** argv) ((uint8_t*)img.pixels)[ipix+1] = 0; ((uint8_t*)img.pixels)[ipix+2] = 0; } else { + struct s3d_attrib attr; float normal[3] = {0.f, 0.f, 0.f}; float tmp[3]; float len; float dot; + f3_normalize(normal, hit.normal); + CHK(s3d_primitive_get_attrib + (&hit.prim, S3D_GEOMETRY_NORMAL, hit.uv, &attr) == RES_OK); + f3_normalize(attr.value, attr.value); + CHK(f3_eq_eps(normal, attr.value, 1.e-3f)); f3_add(pos, org, f3_mulf(pos, dir, hit.distance)); + CHK(s3d_primitive_get_attrib + (&hit.prim, S3D_POSITION, hit.uv, &attr) == RES_OK); + CHK(f3_eq_eps(pos, attr.value, 1.e-3f)); + len = f3_len(f3_sub(pos, pos, center)); CHK(eq_epsf(len, radius, 1.e-3f)); CHK(f3_eq_eps(f3_mulf(tmp, normal, radius), pos, 1.e-3f)); diff --git a/src/test_s3d_utils.h b/src/test_s3d_utils.h @@ -36,6 +36,14 @@ #include <rsys/mem_allocator.h> #include <stdio.h> +static INLINE float +rand_canonic(void) +{ + int r; + while((r = rand()) == RAND_MAX); + return (float)r / (float)RAND_MAX; +} + static void check_memory_allocator(struct mem_allocator* allocator) {