commit e3c0df09d923326dd728cdb3a87164bf2db0ac3e
parent 09d0ba46ffda95f4de759daf0b146479e5fba93d
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 15 Feb 2018 12:28:12 +0100
Add a self-hit filter.
Diffstat:
1 file changed, 46 insertions(+), 8 deletions(-)
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -174,8 +174,6 @@ find_component_Zmax
side = SIDE_BACK;
}
- /* TODO: keep the list of triangle sharing the selected vertex
- * to improve self-hit filter. */
if(cc->max_vrtx[2] < trg_tmp->max_z) {
change = 1; /* Try first to improve z */
}
@@ -469,6 +467,40 @@ get_scn_position(const unsigned ivert, float pos[3], void* ctx) {
f3_set_d3(pos, pt->vec);
}
+struct ray_ctx {
+ component_id_t origin_component;
+ const struct darray_triangle_comp* triangles_comp;
+};
+
+static int
+self_hit_filter
+(const struct s3d_hit* hit,
+ const float ray_org[3],
+ const float ray_dir[3],
+ void* ray_data,
+ void* filter_data)
+{
+ const struct senc_descriptor* desc = filter_data;
+ const struct ray_ctx* ctx = ray_data;
+ const struct triangle_comp* hit_trg_comp;
+ enum side_id hit_side;
+ component_id_t hit_component;
+
+ (void)ray_org; (void)ray_dir;
+ ASSERT(hit && ray_org && ctx && ray_data && desc);
+ ASSERT(hit->prim.prim_id < darray_triangle_comp_size_get(ctx->triangles_comp));
+ hit_trg_comp
+ = darray_triangle_comp_cdata_get(ctx->triangles_comp) + hit->prim.prim_id;
+ hit_side = (hit->normal[2] > 0) ? SIDE_FRONT : SIDE_BACK;
+ hit_component = hit_trg_comp->component[hit_side];
+
+ if(hit_component == ctx->origin_component) {
+ /* self hit */
+ ASSERT(hit->distance < 1e-6);
+ }
+ return (hit_component == ctx->origin_component);
+}
+
static res_T
group_connex_components
(struct senc_descriptor* desc,
@@ -484,6 +516,7 @@ group_connex_components
struct s3d_shape* s3d_shp = NULL;
struct s3d_scene_view* s3d_view = NULL;
struct s3d_vertex_data attribs;
+ struct ray_ctx ray_context;
size_t tmp;
component_id_t cc_count, c;
medium_id_t infinite_medium = MEDIUM_NULL__;
@@ -513,6 +546,8 @@ group_connex_components
ASSERT(desc->scene->nuverts < UINT_MAX);
OK(s3d_mesh_setup_indexed_vertices(s3d_shp, (unsigned)desc->scene->nutris,
get_scn_indices, (unsigned)desc->scene->nuverts, &attribs, 1, desc->scene));
+ s3d_mesh_set_hit_filter_function(s3d_shp, self_hit_filter, desc);
+ ray_context.triangles_comp = triangles_comp;
OK(s3d_scene_attach_shape(s3d_scn, s3d_shp));
OK(s3d_scene_view_create(s3d_scn, S3D_TRACE, &s3d_view));
@@ -523,6 +558,8 @@ group_connex_components
const float dir[3] = { 0, 0, 1 };
const float range[2] = { 0, FLT_MAX };
struct cc_descriptor* const cc = descriptors + c;
+ const struct triangle_comp* origin_trg =
+ darray_triangle_comp_cdata_get(triangles_comp) + cc->max_z_vrtx_id;
ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE);
@@ -545,7 +582,10 @@ group_connex_components
|| trgsides[cc->max_z_side_id].facing_side_id[2]
== TRGSIDE_OPPOSITE(cc->max_z_side_id))));
f3_set_d3(origin, cc->max_vrtx);
- OK(s3d_scene_view_trace_ray(s3d_view, origin, dir, range, NULL, &hit));
+ /* Self-hit data: self hit if hit this component "on the other side" */
+ ray_context.origin_component
+ = origin_trg->component[1- TRGSIDE_2_SIDE(cc->max_z_side_id)];
+ OK(s3d_scene_view_trace_ray(s3d_view, origin, dir, range, &ray_context, &hit));
/* If no hit, the component is facing an infinite medium */
if(S3D_HIT_NONE(&hit)) {
cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
@@ -556,9 +596,8 @@ group_connex_components
infinite_medium_first_side = cc->max_z_side_id;
continue;
}
- if(infinite_medium != cc->medium) {
- /* Medium mismatch!
- * Model topology is broken. */
+ if(infinite_medium == cc->medium) {
+ /* Medium mismatch! Model topology is broken. */
const trg_id_t t1 = TRGSIDE_2_TRG(infinite_medium_first_side);
const trg_id_t t2 = TRGSIDE_2_TRG(cc->max_z_side_id);
const struct triangle_in* triangles_in
@@ -601,7 +640,7 @@ group_connex_components
enum side_id hit_side = (hit.normal[2] > 0) ? SIDE_FRONT : SIDE_BACK;
const side_id_t hit_side_id = TRGIDxSIDE_2_TRGSIDE(hit_trg_id, hit_side);
- ASSERT(hit.prim.prim_id < desc->scene->nutris);
+ ASSERT(hit_trg_id < desc->scene->nutris);
/* Not really the root until following links */
cc->cc_group_root = hit_trg_comp->component[hit_side];
@@ -821,7 +860,6 @@ link_neighbours
/* Compute rotation angle around common edge */
d3_sub(edge, vertices[v2].vec, vertices[v0].vec);
d33_muld3(edge, basis, edge);
- /* TODO: where are invalid triangles detected? */
ASSERT(d3_len(edge) && (edge[0] || edge[1]));
neighbour_info->angle = atan2(edge[1], edge[0]);
if(neighbour_info->angle < 0) neighbour_info->angle += 2 * PI;