commit f86f429e5e9a2fe75e2868376282133778c17643
parent 1f552a8ec7190d4f106d5fcb55ad0807f2a213a4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 15 Mar 2017 14:23:53 +0100
Add the "slices_count_hint" parameter to the ssol_quadric data structure
This parameter is used to control the discretisation of the quadric. By
default, the discretisation level is automatically controlled by the
application.
Diffstat:
3 files changed, 104 insertions(+), 70 deletions(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -159,9 +159,9 @@ static const struct ssol_quadric_parabol SSOL_QUADRIC_PARABOL_NULL =
SSOL_QUADRIC_PARABOL_NULL__;
struct ssol_quadric_hyperbol {
- double img_focal, real_focal;
/* Define (x^2 + y^2) / a^2 - (z - 1/2)^2 / b^2 + 1 = 0
* with a^2 = f - f^2; b = f -1/2; f = real_focal / (img_focal + real_focal) */
+ double img_focal, real_focal;
};
#define SSOL_QUADRIC_HYPERBOL_NULL__ { -1.0 , -1.0 }
static const struct ssol_quadric_hyperbol SSOL_QUADRIC_HYPERBOL_NULL =
@@ -185,13 +185,18 @@ struct ssol_quadric {
/* 3x4 column major transformation of the quadric in object space */
double transform[12];
+
+ /* Hint on the how to discretised */
+ size_t slices_count_hint;
};
#define SSOL_QUADRIC_DEFAULT__ { \
SSOL_QUADRIC_PLANE, \
{SSOL_QUADRIC_PLANE_DEFAULT__}, \
- {1,0,0, 0,1,0, 0,0,1, 0,0,0} \
+ {1,0,0, 0,1,0, 0,0,1, 0,0,0}, \
+ SIZE_MAX /* <=> Use default discretisation */ \
}
+
static const struct ssol_quadric SSOL_QUADRIC_DEFAULT = SSOL_QUADRIC_DEFAULT__;
/* Define the contour of a 2D polygon as well as the clipping operation to
diff --git a/src/ssol_shape.c b/src/ssol_shape.c
@@ -44,7 +44,7 @@ struct mesh_context {
struct quadric_mesh_context {
const double* coords;
const size_t* ids;
- const struct priv_quadric_data* quadric;
+ const union priv_quadric_data* quadric;
const double* transform; /* 3x4 column major matrix */
};
@@ -227,7 +227,7 @@ quadric_mesh_parabol_get_pos(const unsigned ivert, float pos[3], void* ctx)
ASSERT(pos && ctx);
p[0] = msh->coords[i+0];
p[1] = msh->coords[i+1];
- p[2] = parabol_z(p, &msh->quadric->data.parabol);
+ p[2] = parabol_z(p, &msh->quadric->parabol);
/* Transform the position in object space */
d33_muld3(p, msh->transform, p);
@@ -245,7 +245,7 @@ quadric_mesh_hyperbol_get_pos(const unsigned ivert, float pos[3], void* ctx)
ASSERT(pos && ctx);
p[0] = msh->coords[i+0];
p[1] = msh->coords[i+1];
- p[2] = hyperbol_z(p, &msh->quadric->data.hyperbol);
+ p[2] = hyperbol_z(p, &msh->quadric->hyperbol);
/* Transform the position in object space */
d33_muld3(p, msh->transform, p);
@@ -264,7 +264,7 @@ quadric_mesh_parabolic_cylinder_get_pos
ASSERT(pos && ctx);
p[0] = msh->coords[i+0];
p[1] = msh->coords[i+1];
- p[2] = parabolic_cylinder_z(p, &msh->quadric->data.pcylinder);
+ p[2] = parabolic_cylinder_z(p, &msh->quadric->pcylinder);
/* Transform the position in object space */
d33_muld3(p, msh->transform, p);
@@ -837,13 +837,13 @@ punched_shape_set_z_local(const struct ssol_shape* shape, double pt[3])
pt[2] = 0;
break;
case SSOL_QUADRIC_PARABOLIC_CYLINDER:
- pt[2] = parabolic_cylinder_z(pt, &shape->priv_quadric.data.pcylinder);
+ pt[2] = parabolic_cylinder_z(pt, &shape->priv_quadric.pcylinder);
break;
case SSOL_QUADRIC_PARABOL:
- pt[2] = parabol_z(pt, &shape->priv_quadric.data.parabol);
+ pt[2] = parabol_z(pt, &shape->priv_quadric.parabol);
break;
case SSOL_QUADRIC_HYPERBOL:
- pt[2] = hyperbol_z(pt, &shape->priv_quadric.data.hyperbol);
+ pt[2] = hyperbol_z(pt, &shape->priv_quadric.hyperbol);
break;
default: FATAL("Unreachable code\n"); break;
}
@@ -863,15 +863,15 @@ punched_shape_set_normal_local
break;
case SSOL_QUADRIC_PARABOLIC_CYLINDER:
quadric_parabolic_cylinder_gradient_local
- (&shape->priv_quadric.data.pcylinder, pt, normal);
+ (&shape->priv_quadric.pcylinder, pt, normal);
break;
case SSOL_QUADRIC_PARABOL: {
quadric_parabol_gradient_local
- (&shape->priv_quadric.data.parabol, pt, normal);
+ (&shape->priv_quadric.parabol, pt, normal);
break;
case SSOL_QUADRIC_HYPERBOL:
quadric_hyperbol_gradient_local
- (&shape->priv_quadric.data.hyperbol, pt, normal);
+ (&shape->priv_quadric.hyperbol, pt, normal);
break;
}
default: FATAL("Unreachable code\n"); break;
@@ -900,15 +900,15 @@ punched_shape_intersect_local
break;
case SSOL_QUADRIC_PARABOLIC_CYLINDER:
hit = quadric_parabolic_cylinder_intersect_local
- (&shape->priv_quadric.data.pcylinder, org, dir, hint, pt, N, dist);
+ (&shape->priv_quadric.pcylinder, org, dir, hint, pt, N, dist);
break;
case SSOL_QUADRIC_PARABOL:
hit = quadric_parabol_intersect_local
- (&shape->priv_quadric.data.parabol, org, dir, hint, pt, N, dist);
+ (&shape->priv_quadric.parabol, org, dir, hint, pt, N, dist);
break;
case SSOL_QUADRIC_HYPERBOL:
hit = quadric_hyperbol_intersect_local
- (&shape->priv_quadric.data.hyperbol, org, dir, hint, pt, N, dist);
+ (&shape->priv_quadric.hyperbol, org, dir, hint, pt, N, dist);
break;
default: FATAL("Unreachable code\n"); break;
}
@@ -930,32 +930,23 @@ shape_release(ref_T* ref)
}
/* Return the parabol discretisation parameter */
-static INLINE size_t
-priv_data_parabol_setup
+static FINLINE void
+priv_parabol_data_setup
(struct priv_parabol_data* data,
- struct ssol_quadric_parabol* parabol,
- const double lower[3],
- const double upper[3])
+ const struct ssol_quadric_parabol* parabol)
{
- double max_z;
- ASSERT(data && parabol && lower && upper);
-
+ ASSERT(data && parabol);
data->focal = parabol->focal;
data->_1_4f = 1 / (4.0 * parabol->focal);
- max_z = MMAX(parabol_z(lower, data), parabol_z(upper, data));
- return MMIN(50, (size_t) (3 + sqrt(max_z) * 6));
}
-static INLINE size_t
-priv_data_hyperbol_setup
+static FINLINE void
+priv_hyperbol_data_setup
(struct priv_hyperbol_data* data,
- struct ssol_quadric_hyperbol* hyperbol,
- const double lower[3],
- const double upper[3])
+ const struct ssol_quadric_hyperbol* hyperbol)
{
double g, f, a2;
- double max_z;
- ASSERT(data && hyperbol && lower && upper);
+ ASSERT(data && hyperbol);
/* Re-dimensionalize */
g = hyperbol->real_focal + hyperbol->img_focal;
@@ -966,25 +957,76 @@ priv_data_hyperbol_setup
data->abs_b = g * fabs(f - 0.5);
data->_a2_b2 = a2 / (data->abs_b * data->abs_b);
data->_1_a2 = 1 / a2;
- max_z = MMAX(hyperbol_z(lower, data), hyperbol_z(upper, data));
- return MMIN(50, (size_t) (3 + sqrt(max_z) * 6));
}
-static INLINE size_t
-priv_data_parabolic_cylinder_setup
+static FINLINE void
+priv_parabolic_cylinder_data_setup
(struct priv_pcylinder_data* data,
- struct ssol_quadric_parabolic_cylinder* parabolic_cylinder,
+ const struct ssol_quadric_parabolic_cylinder* parabolic_cylinder)
+{
+ ASSERT(data && parabolic_cylinder);
+ data->focal = parabolic_cylinder->focal;
+ data->_1_4f = 1 / (4.0 * parabolic_cylinder->focal);
+}
+
+static INLINE void
+priv_quadric_data_setup
+ (union priv_quadric_data* priv_data,
+ const struct ssol_quadric* quadric)
+{
+ ASSERT(priv_data && quadric);
+ switch(quadric->type) {
+ case SSOL_QUADRIC_PLANE: /* Do nothing */ break;
+ case SSOL_QUADRIC_PARABOL:
+ priv_parabol_data_setup
+ (&priv_data->parabol, &quadric->data.parabol);
+ break;
+ case SSOL_QUADRIC_HYPERBOL:
+ priv_hyperbol_data_setup
+ (&priv_data->hyperbol, &quadric->data.hyperbol);
+ break;
+ case SSOL_QUADRIC_PARABOLIC_CYLINDER:
+ priv_parabolic_cylinder_data_setup
+ (&priv_data->pcylinder, &quadric->data.parabolic_cylinder);
+ break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+}
+
+static INLINE size_t
+priv_quadric_data_compute_slices_count
+ (const enum ssol_quadric_type type,
+ const union priv_quadric_data* priv_data,
const double lower[3],
const double upper[3])
{
+ size_t nslices;
double max_z;
- ASSERT(data && parabolic_cylinder && lower && upper);
+ ASSERT(priv_data && lower && upper);
- data->focal = parabolic_cylinder->focal;
- data->_1_4f = 1 / (4.0 * parabolic_cylinder->focal);
- max_z = MMAX
- (parabolic_cylinder_z(lower, data), parabolic_cylinder_z(upper, data));
- return MMIN(50, (size_t) (3 + sqrt(max_z) * 6));
+ switch(type) {
+ case SSOL_QUADRIC_PLANE: nslices = 50; break;
+ case SSOL_QUADRIC_PARABOL:
+ max_z = MMAX
+ (parabol_z(lower, &priv_data->parabol),
+ parabol_z(upper, &priv_data->parabol));
+ nslices = MMIN(50, (size_t)(3 + sqrt(max_z) * 6));
+ break;
+ case SSOL_QUADRIC_HYPERBOL:
+ max_z = MMAX
+ (hyperbol_z(lower, &priv_data->hyperbol),
+ hyperbol_z(upper, &priv_data->hyperbol));
+ nslices = MMIN(50, (size_t)(3 + sqrt(max_z) * 6));
+ break;
+ case SSOL_QUADRIC_PARABOLIC_CYLINDER:
+ max_z = MMAX
+ (parabolic_cylinder_z(lower, &priv_data->pcylinder),
+ parabolic_cylinder_z(upper, &priv_data->pcylinder));
+ nslices = MMIN(50, (size_t)(3 + sqrt(max_z) * 6));
+ break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+ return nslices;
}
/*******************************************************************************
@@ -1226,25 +1268,15 @@ ssol_punched_surface_setup
goto error;
}
- /* Define the #slices of the discretized quadric & setup internal data */
- switch (psurf->quadric->type) {
- case SSOL_QUADRIC_PLANE:
- nslices = 1;
- break;
- case SSOL_QUADRIC_PARABOL:
- nslices = priv_data_parabol_setup(&shape->priv_quadric.data.parabol,
- &psurf->quadric->data.parabol, lower, upper);
- break;
- case SSOL_QUADRIC_HYPERBOL:
- nslices = priv_data_hyperbol_setup(&shape->priv_quadric.data.hyperbol,
- &psurf->quadric->data.hyperbol, lower, upper);
- break;
- case SSOL_QUADRIC_PARABOLIC_CYLINDER:
- nslices = priv_data_parabolic_cylinder_setup
- (&shape->priv_quadric.data.pcylinder,
- &psurf->quadric->data.parabolic_cylinder,lower, upper);
- break;
- default: FATAL("Unreachable code\n"); break;
+ /* Setup internal data */
+ priv_quadric_data_setup(&shape->priv_quadric, psurf->quadric);
+
+ /* Define the #slices of the discretized quadric */
+ if(psurf->quadric->slices_count_hint != SIZE_MAX) {
+ nslices = psurf->quadric->slices_count_hint;
+ } else {
+ nslices = priv_quadric_data_compute_slices_count
+ (shape->quadric.type, &shape->priv_quadric, lower, upper);
}
res = build_triangulated_plane(&coords, &ids, lower, upper, nslices);
diff --git a/src/ssol_shape_c.h b/src/ssol_shape_c.h
@@ -43,13 +43,10 @@ struct priv_pcylinder_data {
double _1_4f;
};
-struct priv_quadric_data {
- enum ssol_quadric_type type;
- union {
- struct priv_hyperbol_data hyperbol;
- struct priv_parabol_data parabol;
- struct priv_pcylinder_data pcylinder;
- } data;
+union priv_quadric_data {
+ struct priv_hyperbol_data hyperbol;
+ struct priv_parabol_data parabol;
+ struct priv_pcylinder_data pcylinder;
};
struct ssol_shape {
@@ -57,7 +54,7 @@ struct ssol_shape {
struct s3d_shape* shape_rt; /* Star-3D shape to ray-trace */
struct s3d_shape* shape_samp; /* Star-3D shape to sample */
- struct priv_quadric_data priv_quadric;
+ union priv_quadric_data priv_quadric;
struct ssol_quadric quadric;
double shape_rt_area, shape_samp_area;