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 162a68c8bffba4d13b5e803a7c6750f39b5114bb
parent 043dc3be804f2240d9d3a804ec02181730d00ea5
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 21 Apr 2020 10:38:06 +0200

Add a closest_point test on returned UV

Check that the returned barycentric coordinates are now correct wrt
their domain.

Diffstat:
Msrc/test_s3d_closest_point.c | 46++++++++++++++++++++++++++++++++++++++--------
1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/src/test_s3d_closest_point.c b/src/test_s3d_closest_point.c @@ -806,13 +806,14 @@ triangle_get_ids(const unsigned itri, unsigned ids[3], void* ctx) static void triangle_get_pos(const unsigned ivert, float pos[3], void* ctx) { - (void)ctx; + float* vertices = ctx; + CHK(ctx); CHK(ivert < 3); CHK(pos); switch(ivert) { /* Setup a random triangle */ - case 0: f3(pos, -0.5f, -0.3f, 0.1f); break; - case 1: f3(pos, -0.4f, 0.2f, 0.3f); break; - case 2: f3(pos, 0.7f, 0.01f, -0.5f); break; + case 0: f3_set(pos, vertices+0); break; + case 1: f3_set(pos, vertices+3); break; + case 2: f3_set(pos, vertices+6); break; default: FATAL("Unreachable code\n"); break; } } @@ -820,6 +821,7 @@ triangle_get_pos(const unsigned ivert, float pos[3], void* ctx) static void test_single_triangle(struct s3d_device* dev) { + float vertices[9]; struct s3d_vertex_data vdata = S3D_VERTEX_DATA_NULL; struct s3d_hit hit = S3D_HIT_NULL; struct s3d_scene* scn = NULL; @@ -830,8 +832,13 @@ test_single_triangle(struct s3d_device* dev) float pos[3] = {0,0,0}; float closest_pos[3] = {0,0,0}; float low[3], upp[3], mid[3]; + union { float f; uint32_t ui32; } ucast; size_t i; + f3(vertices+0, -0.5f, -0.3f, 0.1f); + f3(vertices+3, -0.4f, 0.2f, 0.3f); + f3(vertices+6, 0.7f, 0.01f, -0.5f); + CHK(s3d_scene_create(dev, &scn) == RES_OK); CHK(s3d_shape_create_mesh(dev, &msh) == RES_OK); CHK(s3d_scene_attach_shape(scn, msh) == RES_OK); @@ -840,13 +847,13 @@ test_single_triangle(struct s3d_device* dev) vdata.type = S3D_FLOAT3; vdata.get = triangle_get_pos; CHK(s3d_mesh_setup_indexed_vertices - (msh, 1, triangle_get_ids, 3, &vdata, 1, NULL) == RES_OK); + (msh, 1, triangle_get_ids, 3, &vdata, 1, vertices) == RES_OK); CHK(s3d_scene_view_create(scn, S3D_TRACE, &view) == RES_OK); - triangle_get_pos(0, v0, NULL); - triangle_get_pos(1, v1, NULL); - triangle_get_pos(2, v2, NULL); + triangle_get_pos(0, v0, vertices); + triangle_get_pos(1, v1, vertices); + triangle_get_pos(2, v2, vertices); /* Compute the triangle AABB */ low[0] = MMIN(MMIN(v0[0], v1[0]), v2[0]); @@ -896,6 +903,29 @@ test_single_triangle(struct s3d_device* dev) CHK(!S3D_HIT_NONE(&hit)); CHK(hit.distance == nextafterf(radius, 0.f)); } + CHK(s3d_scene_view_ref_put(view) == RES_OK); + + /* Setup a triangle and a query position that exhibited a precision issue on + * the returned barycentric coordinate and check that this bug is now fixed */ + ucast.ui32 = 0x40400000; vertices[0] = ucast.f; + ucast.ui32 = 0xc1200000; vertices[1] = ucast.f; + ucast.ui32 = 0xbfc00000; vertices[2] = ucast.f; + ucast.ui32 = 0x40400000; vertices[3] = ucast.f; + ucast.ui32 = 0xc1200000; vertices[4] = ucast.f; + ucast.ui32 = 0x3fc00000; vertices[5] = ucast.f; + ucast.ui32 = 0x3f6d5337; vertices[6] = ucast.f; + ucast.ui32 = 0xc0e4b2d5; vertices[7] = ucast.f; + ucast.ui32 = 0xbfc00000; vertices[8] = ucast.f; + f3(pos, 2, -10, 1); + + CHK(s3d_mesh_setup_indexed_vertices + (msh, 1, triangle_get_ids, 3, &vdata, 1, vertices) == RES_OK); + CHK(s3d_scene_view_create(scn, S3D_TRACE, &view) == RES_OK); + CHK(s3d_scene_view_closest_point(view, pos, (float)INF, NULL, &hit) == RES_OK); + CHK(!S3D_HIT_NONE(&hit)); + CHK(0 <= hit.uv[0] && hit.uv[0] <= 1); + CHK(0 <= hit.uv[1] && hit.uv[1] <= 1); + CHK(hit.uv[0] + hit.uv[1] <= 1); CHK(s3d_shape_ref_put(msh) == RES_OK); CHK(s3d_scene_view_ref_put(view) == RES_OK);