commit bfee440c85d7f6622b2e512d0e767feb67a19a6d
parent 415219a3c1e70f8df43ec19bffaefe4b4f5d1f6c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 22 Apr 2021 11:44:58 +0200
Update ray filter function for the combustion chamber geometry
Replace the previous two filter functions by one that ignores the
intersections with the surfaces pointing toward a user defined medium.
Diffstat:
2 files changed, 36 insertions(+), 92 deletions(-)
diff --git a/src/combustion/htrdr_combustion_geometry_ray_filter.c b/src/combustion/htrdr_combustion_geometry_ray_filter.c
@@ -17,12 +17,18 @@
#include "combustion/htrdr_combustion_geometry_ray_filter.h"
+#include "core/htrdr_interface.h"
+#include "core/htrdr_geometry.h"
+
+#include <rsys/float3.h>
+
+#include <string.h>
/*******************************************************************************
* Local functions
******************************************************************************/
int
-geometry_ray_filter_discard_first_hit
+geometry_ray_filter_discard_medium_interface
(const struct s3d_hit* hit,
const float ray_org[3],
const float ray_dir[3],
@@ -30,80 +36,33 @@ geometry_ray_filter_discard_first_hit
void* filter_data)
{
struct geometry_ray_filter_context* ctx = ray_data;
+ struct htrdr_interface interf = HTRDR_INTERFACE_NULL;
+ const struct htrdr_mtl* mtl = NULL;
+ float N[3];
+ int hit_front;
int discard = 0;
ASSERT(hit && ray_org && ray_dir && ray_data && !S3D_HIT_NONE(hit));
(void)ray_org, (void)ray_dir, (void)filter_data;
- /* Note that the surfaces are not intersected in order. In this filter
- * function, we save in ctx->hit_tmp__ the current "first intersection" and
- * in ctx->hit the second one that is the candidate intersection. */
+ /* Recover the interface of the intersected surface */
+ htrdr_geometry_get_interface(ctx->geom, hit, &interf);
+
+ /* Define if the ray intersects the front face of the surface */
+ f3_normalize(N, hit->normal); /* Limit the numerical instabilities */
+ hit_front = f3_dot(ray_dir, N) < 0;
- if(hit->distance > ctx->hit_tmp__.distance) {
- /* An intersection was already registered as the first hit. Accept the
- * input hit and update the ctx->hit if necessary */
- discard = 0;
- if(hit->distance < ctx->hit.distance) {
- ctx->hit = *hit;
- }
+ /* Recover the material in which the ray is traced */
+ if(hit_front) {
+ mtl = &interf.mtl_front;
} else {
- /* No intersection has been stored or the submitted intersection is closer
- * than the one recorded as "first intersection". This new intersection
- * becomes the new first hit and is therefore rejected while the previous
- * become the candidate intersection. */
- discard = 1;
- ASSERT(ctx->hit.distance >= ctx->hit_tmp__.distance);
- ctx->hit = ctx->hit_tmp__;
- ctx->hit_tmp__ = *hit;
+ mtl = &interf.mtl_back;
}
- return discard;
-}
-
-int
-geometry_ray_filter_discard_last_hit
- (const struct s3d_hit* hit,
- const float ray_org[3],
- const float ray_dir[3],
- void* ray_data,
- void* filter_data)
-{
- struct geometry_ray_filter_context* ctx = ray_data;
- int discard = 0;
- ASSERT(hit && ray_org && ray_dir && ray_data && !S3D_HIT_NONE(hit));
- (void)ray_org, (void)ray_dir, (void)filter_data;
-
- /* Note that the surfaces are not intersected in order. In this filter
- * function, we save in ctx->hit_tmp__ the current "last intersection" and
- * in ctx->hit the closest one exepted this last intersection. */
- if(S3D_HIT_NONE(&ctx->hit_tmp__)) {
- /* No intersection was registered. The submitted hit would be the last one.
- * So discard it and register the hit as the last intersect */
- discard = 1;
- ctx->hit_tmp__ = *hit;
-
- } else if(hit->distance > ctx->hit_tmp__.distance) {
- /* A "last intersection" has already been stored but is closer than the
- * submitted intersection. This new intersection could be the real “last
- * intersection”. So we save this intersection and reject it */
- discard = 1;
- ASSERT(S3D_HIT_NONE(&ctx->hit)
- || ctx->hit_tmp__.distance >= ctx->hit.distance);
-
- /* Also, if the nearest intersection was not already defined, we set it to
- * the last previously saved intersection; if it was already defined, it
- * would necessarily be the closest. */
- if(S3D_HIT_NONE(&ctx->hit)) {
- ctx->hit = ctx->hit_tmp__;
- }
-
- ctx->hit_tmp__ = *hit; /* Save last intersection */
-
- } else if(hit->distance < ctx->hit.distance) {
- /* A closest intersection that is not the last one is found. Keep and
- * register this intersection */
- discard = 0;
- ctx->hit = *hit;
- }
+ /* The material should be semi-transparent and thus could not have a BRDF */
+ ASSERT(mtl->mrumtl == NULL);
+ /* Discard the intersection if the ray comes from the material to filter */
+ discard = !strcmp(mtl->name, ctx->medium_name);
return discard;
}
+
diff --git a/src/combustion/htrdr_combustion_geometry_ray_filter.h b/src/combustion/htrdr_combustion_geometry_ray_filter.h
@@ -22,41 +22,26 @@
#include <rsys/rsys.h>
struct geometry_ray_filter_context {
- /* This is the real hit to use. The one returned by the trace ray function is
- * only used as a "early stop" of the tray tracing process */
- struct s3d_hit hit;
+ struct htrdr_geometry* geom;
- struct s3d_hit hit_tmp__; /* Temporary internal data */
+ /* Name of the medium attached to the interface to filter. An intersection is
+ * ignorer if the side of the intersected surface points toward the medium
+ * whose name is `medium_name`. */
+ const char* medium_name;
};
-#define GEOMETRY_RAY_FILTER_CONTEXT_NULL__ {S3D_HIT_NULL__, S3D_HIT_NULL__}
+#define GEOMETRY_RAY_FILTER_CONTEXT_NULL__ {NULL, NULL}
static const struct geometry_ray_filter_context
GEOMETRY_RAY_FILTER_CONTEXT_NULL = GEOMETRY_RAY_FILTER_CONTEXT_NULL__;
-/* Filter function used to ignore the first intersection along the ray. Note
- * that the intersection to use is output in the 'hit' member variable of the
- * 'struct geometry_filter_context' data structure pointed to by the 'ray_data'
- * input argument. The intersection returned by the ray tracing procedure
- * itself is actually just a temporary variable used to prematurely stop ray
- * tracing. */
+/* Filter function used to ignore the intersections with surfaces pointing
+ * toward a user defined medium */
extern LOCAL_SYM int
-geometry_ray_filter_discard_first_hit
+geometry_ray_filter_discard_medium_interface
(const struct s3d_hit* hit,
const float ray_org[3],
const float ray_dir[3],
- void* ray_data, /* Must point to a struct geometry_filter_context */
- void* filter_data);
-
-/* Quite similar filtering function to the previous one, but this time it
- * filters the last intersection along the ray, not the first. This means that
- * if the ray intersects only one surface, it is assumed that the ray does not
- * intersect anything. */
-extern LOCAL_SYM int
-geometry_ray_filter_discard_last_hit
- (const struct s3d_hit* hit,
- const float ray_org[3],
- const float ray_dir[3],
- void* ray_data, /* Must point to a struct geometry_filter_context */
+ void* ray_data, /* Must point to a struct geometry_ray_filter_context */
void* filter_data);
#endif /* HTRDR_COMBUSTION_GEOMETRY_RAY_FILTER_H */