commit 06316573d1ed8c7afe3df2f9b19d1696041ab575
parent 94246086320dbb5c8260b8e1fbf7b1d80d8176b0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 18 May 2016 10:33:33 +0200
Handle self hit with the Star-3D hit filter function
Diffstat:
3 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/src/s4vs.c b/src/s4vs.c
@@ -120,6 +120,7 @@ import_obj(const char* filename, struct s3d_scene** out_scene)
struct s3d_scene* scene = NULL;
struct s3daw* s3daw = NULL;
const int VERBOSE = 0;
+ size_t ishape, nshapes;
res_T res = RES_OK;
ASSERT(out_scene);
@@ -127,8 +128,14 @@ import_obj(const char* filename, struct s3d_scene** out_scene)
CALL(s3d_device_create(NULL, NULL, VERBOSE, &s3d));
CALL(s3daw_create(NULL, NULL, NULL, NULL, s3d, VERBOSE, &s3daw));
CALL(s3daw_load(s3daw, filename));
+ CALL(s3daw_get_shapes_count(s3daw, &nshapes));
CALL(s3d_scene_create(s3d, &scene));
- CALL(s3daw_attach_to_scene(s3daw, scene));
+ FOR_EACH(ishape, 0, nshapes) {
+ struct s3d_shape* shape;
+ CALL(s3daw_get_shape(s3daw, ishape, &shape));
+ CALL(s3d_mesh_set_hit_filter_function(shape, s4vs_discard_self_hit, NULL));
+ CALL(s3d_scene_attach_shape(scene, shape));
+ }
#undef CALL
exit:
diff --git a/src/s4vs_realization.c b/src/s4vs_realization.c
@@ -34,13 +34,36 @@
#include "s4vs_realization.h"
+/*******************************************************************************
+ * Helper function
+ ******************************************************************************/
+int
+s4vs_discard_self_hit
+ (const struct s3d_hit* hit,
+ const float ray_org[3],
+ const float ray_dir[3],
+ void* ray_data,
+ void* filter_data)
+{
+ const struct s3d_primitive* prim_from = ray_data;
+
+ /* Avoid unused variable warn */
+ (void)ray_org, (void)ray_dir, (void)filter_data;
+
+ return prim_from ? S3D_PRIMITIVE_EQ(prim_from, &hit->prim) : 0;
+}
+
+/*******************************************************************************
+ * 4V/S integrand
+ ******************************************************************************/
res_T
s4vs_realization(void* out_length, struct ssp_rng* rng, void* context)
{
struct s4vs_context* ctx = (struct s4vs_context*)context;
struct s3d_attrib attrib;
struct s3d_primitive prim;
- float normal[3], u[4], x[3], range[2], st[2];
+ float normal[3], u[4], x[3], st[2];
+ const float range[2] = {0.f, FLT_MAX};
struct s3d_hit hit;
double w = 0;
double sigma = 0;
@@ -63,12 +86,7 @@ s4vs_realization(void* out_length, struct ssp_rng* rng, void* context)
ssp_ran_hemisphere_cos(rng, normal, u);
/* Find the 1st hit from the sampled location along the sampled direction */
- range[0] = 1.e-6f;
- range[1] = (float)INF;
- do {
- S3D(scene_trace_ray(ctx->scene, x, u, range, &hit));
- range[0] += 1.e-6f;
- } while(S3D_PRIMITIVE_EQ(&hit.prim, &prim)); /* Handle self-hit */
+ S3D(scene_trace_ray(ctx->scene, x, u, range, &prim, &hit));
/* No intersection <=> numerical imprecision or geometry leakage */
if(S3D_HIT_NONE(&hit)) return RES_UNKNOWN_ERR;
@@ -83,9 +101,7 @@ s4vs_realization(void* out_length, struct ssp_rng* rng, void* context)
ssp_ran_sphere_hg(rng, u, ctx->g, u);
/* sample a new direction */
- range[0] = 0;
- range[1] = (float)INF;
- S3D(scene_trace_ray(ctx->scene, x, u, range, &hit));
+ S3D(scene_trace_ray(ctx->scene, x, u, range, NULL, &hit));
w = w + sigma;
diff --git a/src/s4vs_realization.h b/src/s4vs_realization.h
@@ -41,6 +41,15 @@ struct s4vs_context {
double g;
};
+/* Hit filter function used to handle auto intersection */
+extern int
+s4vs_discard_self_hit
+ (const struct s3d_hit* hit,
+ const float ray_org[3],
+ const float ray_dir[3],
+ void* ray_data,
+ void* filter_data);
+
/*******************************************************************************
* MC realization function
******************************************************************************/