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:
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);