commit 49160bcfd6e6247d1941043c5753c3655f1a8175
parent b9dd0b8492c6c7b13b773972ef09f00b764e1d3a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 2 Sep 2016 15:13:00 +0200
Finalise the implementation of the ssol_punched_surface function
Diffstat:
3 files changed, 134 insertions(+), 23 deletions(-)
diff --git a/src/ssol_shape.c b/src/ssol_shape.c
@@ -27,11 +27,19 @@
#include <star/scpr.h>
+#include <limits.h> /* UINT_MAX constant */
+
struct mesh_context {
const double* coords;
const size_t* ids;
};
+struct quadric_mesh_context {
+ const double* coords;
+ const size_t* ids;
+ double focal; /* Use by parabol and parabolic cylinder quadrics */
+};
+
/*******************************************************************************
* Helper functions
******************************************************************************/
@@ -119,7 +127,7 @@ ssol_to_scpr_clip_op(const enum ssol_clipping_op clip_op)
switch(clip_op) {
case SSOL_AND: op = SCPR_AND; break;
case SSOL_SUB: op = SCPR_SUB; break;
- default: FATAL("Unreachable code \n"); break;
+ default: FATAL("Unreachable code.\n"); break;
}
return op;
}
@@ -145,11 +153,62 @@ mesh_get_pos(const size_t ivert, double pos[2], void* ctx)
pos[1] = msh->coords[i+1];
}
+static void
+quadric_mesh_get_ids(const unsigned itri, unsigned ids[3], void* ctx)
+{
+ const size_t i = itri*3/*#ids per triangle*/;
+ const struct quadric_mesh_context* msh = ctx;
+ ASSERT(ids && ctx);
+ ids[0] = (unsigned)msh->ids[i+0];
+ ids[1] = (unsigned)msh->ids[i+1];
+ ids[2] = (unsigned)msh->ids[i+2];
+}
+
+static void
+quadric_mesh_plane_get_pos(const unsigned ivert, float pos[3], void* ctx)
+{
+ const size_t i = ivert*2/*#coords per vertex*/;
+ const struct quadric_mesh_context* msh = ctx;
+ ASSERT(pos && ctx);
+ pos[0] = (float)msh->coords[i+0];
+ pos[1] = (float)msh->coords[i+1];
+ pos[2] = 0.f;
+}
+
+static void
+quadric_mesh_parabol_get_pos(const unsigned ivert, float pos[3], void* ctx)
+{
+ const size_t i = ivert*2/*#coords per vertex*/;
+ const struct quadric_mesh_context* msh = ctx;
+ double x, y;
+ ASSERT(pos && ctx);
+ x = msh->coords[i+0];
+ y = msh->coords[i+1];
+ pos[0] = (float)x;
+ pos[1] = (float)y;
+ pos[2] = (float)((x*x + y*y) / (4.0*msh->focal));
+}
+
+static void
+quadric_mesh_parabolic_cylinder_get_pos
+ (const unsigned ivert, float pos[3], void* ctx)
+{
+ const size_t i = ivert*2/*#coords per vertex*/;
+ const struct quadric_mesh_context* msh = ctx;
+ double x, y;
+ ASSERT(pos && ctx);
+ x = msh->coords[i+0];
+ y = msh->coords[i+1];
+ pos[0] = (float)x;
+ pos[1] = (float)y;
+ pos[2] = (float)((y*y) / (4.0*msh->focal));
+}
+
static FINLINE int
aabb_is_degenerated(const double lower[2], const double upper[2])
{
ASSERT(lower && upper);
- return lower[0] > upper[0] || lower[1] > upper[1];
+ return lower[0] >= upper[0] || lower[1] >= upper[1];
}
static void
@@ -203,7 +262,10 @@ build_triangulated_plane
d2_sub(size, upper, lower);
size_max = MMAX(size[0], size[1]);
- if(eq_eps(size_max, 0, 1.e-6)) goto exit;
+ if(eq_eps(size_max, 0, 1.e-6)) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
delta = size_max / (double)nsteps;
nsteps2[0] = (size_t)ceil(size[0] / delta);
@@ -335,6 +397,48 @@ error:
goto exit;
}
+static res_T
+quadric_setup_s3d_shape
+ (const struct ssol_quadric* quadric,
+ const struct darray_double* coords,
+ const struct darray_size_t* ids,
+ struct s3d_shape* shape)
+{
+ struct quadric_mesh_context ctx;
+ struct s3d_vertex_data vdata;
+ unsigned nverts;
+ unsigned ntris;
+ ASSERT(quadric && coords && ids && shape);
+ ASSERT(darray_double_size_get(coords)%2 == 0);
+ ASSERT(darray_size_t_size_get(ids)%3 == 0);
+ ASSERT(darray_double_size_get(coords)/2 <= UINT_MAX);
+ ASSERT(darray_size_t_size_get(ids)/3 <= UINT_MAX);
+
+ nverts = (unsigned)darray_double_size_get(coords) / 2/*#coords per vertex*/;
+ ntris = (unsigned)darray_size_t_size_get(ids) / 3/*#ids per triangle*/;
+ ctx.coords = darray_double_cdata_get(coords);
+ ctx.ids = darray_size_t_cdata_get(ids);
+
+ vdata.usage = S3D_POSITION;
+ vdata.type = S3D_FLOAT3;
+ switch(quadric->type) {
+ case SSOL_QUADRIC_PARABOL:
+ ctx.focal = quadric->data.parabol.focal;
+ vdata.get = quadric_mesh_parabol_get_pos;
+ break;
+ case SSOL_QUADRIC_PARABOLIC_CYLINDER:
+ ctx.focal = quadric->data.parabolic_cylinder.focal;
+ vdata.get = quadric_mesh_parabolic_cylinder_get_pos;
+ break;
+ case SSOL_QUADRIC_PLANE:
+ vdata.get = quadric_mesh_plane_get_pos;
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+
+ return s3d_mesh_setup_indexed_vertices
+ (shape, ntris, quadric_mesh_get_ids, nverts, &vdata, 1, &ctx);
+}
static res_T
shape_create
@@ -454,7 +558,7 @@ ssol_punched_surface_setup
carvings_compute_aabb(psurf->carvings, psurf->nb_carvings, lower, upper);
if(aabb_is_degenerated(lower, upper)) {
log_error(shape->dev,
- "%s: infinite punched surface; no `and' carving polygon is defined.\n",
+ "%s: infinite or null punched surface.\n",
FUNC_NAME);
res = RES_BAD_ARG;
goto error;
@@ -470,8 +574,9 @@ ssol_punched_surface_setup
(&coords, &ids, shape->dev->scpr_mesh, psurf->carvings, psurf->nb_carvings);
if(res != RES_OK) goto error;
- /* TODO displace the triangulated plane vertices */
- /* TODO register the displaced triangulated plane in the s3d_shape */
+ res = quadric_setup_s3d_shape
+ (psurf->quadric, &coords, &ids, shape->s3d_shape);
+ if(res != RES_OK) goto error;
exit:
darray_double_release(&coords);
@@ -528,7 +633,7 @@ ssol_mesh_setup
attrs[i].usage = SSOL_TO_S3D_TEXCOORD;
attrs[i].type = S3D_FLOAT2;
break;
- default: FATAL("Unreachable code \n"); break;
+ default: FATAL("Unreachable code.\n"); break;
}
}
res = s3d_mesh_setup_indexed_vertices
diff --git a/src/test_ssol_geometries.h b/src/test_ssol_geometries.h
@@ -25,16 +25,14 @@ struct desc {
* Plane
******************************************************************************/
static const float square_walls [] = {
- -1, -1, 0,
- 1, -1, 0,
- 1, 1, 0,
- -1, 1, 0
+ -1.f, -1.f, 0.f,
+ 1.f, -1.f, 0.f,
+ 1.f, 1.f, 0.f,
+ -1.f, 1.f, 0.f
};
const unsigned square_walls_nverts = sizeof(square_walls) / sizeof(float[3]);
-const unsigned square_walls_ids [] = {
- 0, 2, 1, 2, 0, 3
-};
+const unsigned square_walls_ids [] = { 0, 2, 1, 2, 0, 3 };
const unsigned square_walls_ntris = sizeof(square_walls_ids) / sizeof(unsigned[3]);
static const struct desc square_walls_desc = { square_walls, square_walls_ids };
@@ -74,6 +72,7 @@ get_ids(const unsigned itri, unsigned ids[3], void* data)
const unsigned id = itri * 3;
struct desc* desc = data;
NCHECK(desc, NULL);
+ NCHECK(ids, NULL);
ids[0] = desc->indices[id + 0];
ids[1] = desc->indices[id + 1];
ids[2] = desc->indices[id + 2];
@@ -84,6 +83,7 @@ get_position(const unsigned ivert, float position[3], void* data)
{
struct desc* desc = data;
NCHECK(desc, NULL);
+ NCHECK(position, NULL);
position[0] = desc->vertices[ivert * 3 + 0];
position[1] = desc->vertices[ivert * 3 + 1];
position[2] = desc->vertices[ivert * 3 + 2];
@@ -92,7 +92,8 @@ get_position(const unsigned ivert, float position[3], void* data)
static INLINE void
get_normal(const unsigned ivert, float normal[3], void* data)
{
- (void) ivert, (void) data;
+ (void)ivert, (void)data;
+ NCHECK(normal, NULL);
normal[0] = 1.f;
normal[1] = 0.f;
normal[2] = 0.f;
@@ -101,7 +102,8 @@ get_normal(const unsigned ivert, float normal[3], void* data)
static INLINE void
get_uv(const unsigned ivert, float uv[2], void* data)
{
- (void) ivert, (void) data;
+ (void)ivert, (void)data;
+ NCHECK(uv, NULL);
uv[0] = -1.f;
uv[1] = 1.f;
}
@@ -109,9 +111,11 @@ get_uv(const unsigned ivert, float uv[2], void* data)
static INLINE void
get_polygon_vertices(const size_t ivert, double position[2], void* ctx)
{
- (void) ivert, (void) ctx;
- position[0] = -1.f;
- position[1] = 1.f;
+ const double* verts = ctx;
+ NCHECK(position, NULL);
+ NCHECK(ctx, NULL);
+ position[0] = verts[ivert*2+0];
+ position[1] = verts[ivert*2+1];
}
#endif /* TEST_SSOL_GEOMETRIES_H */
diff --git a/src/test_ssol_shape.c b/src/test_ssol_shape.c
@@ -33,6 +33,8 @@ main(int argc, char** argv)
struct ssol_punched_surface punched_surface;
struct ssol_carving carving;
struct ssol_quadric quadric;
+ const double polygon[] = { -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0 };
+ const size_t npolygon_verts = sizeof(polygon)/sizeof(double[2]);
(void) argc, (void) argv;
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
@@ -43,7 +45,7 @@ main(int argc, char** argv)
logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
CHECK(ssol_device_create
- (&logger, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK);
+ (&logger, &allocator, SSOL_NTHREADS_DEFAULT, 1, &dev), RES_OK);
CHECK(ssol_shape_create_mesh(NULL, NULL), RES_BAD_ARG);
CHECK(ssol_shape_create_mesh(dev, NULL), RES_BAD_ARG);
@@ -93,8 +95,8 @@ main(int argc, char** argv)
carving.get = get_polygon_vertices;
carving.operation = SSOL_AND;
- carving.nb_vertices = 1;
- carving.context = NULL;
+ carving.nb_vertices = npolygon_verts;
+ carving.context = &polygon;
quadric.type = SSOL_QUADRIC_PLANE;
punched_surface.nb_carvings = 1;
punched_surface.quadric = &quadric;
@@ -119,7 +121,7 @@ main(int argc, char** argv)
carving.nb_vertices = 0;
CHECK(ssol_punched_surface_setup(shape, &punched_surface), RES_BAD_ARG);
- carving.nb_vertices = 1;
+ carving.nb_vertices = npolygon_verts;
carving.get = NULL;
CHECK(ssol_punched_surface_setup(shape, &punched_surface), RES_BAD_ARG);