commit 9b0fd6fd923b31d78a6d31dc65d1776db546de7e
parent f1b509ca2c98a7fdb8122a7f648d659fd60b6816
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 26 Apr 2021 22:06:11 +0200
Upd the profile of the sgs_geometry_trace_ray function
Diffstat:
2 files changed, 77 insertions(+), 28 deletions(-)
diff --git a/src/sgs_geometry.c b/src/sgs_geometry.c
@@ -30,9 +30,9 @@
struct hit_filter_context {
float range[2];
- struct s3d_hit hit_from;
+ struct sgs_s3d_position pos_from;
};
-#define HIT_FILTER_CONTEXT_NULL__ {{0,FLT_MAX}, S3D_HIT_NULL__}
+#define HIT_FILTER_CONTEXT_NULL__ {{0,FLT_MAX}, SGS_S3D_POSITION_NULL__}
static const struct hit_filter_context HIT_FILTER_CONTEXT_NULL =
HIT_FILTER_CONTEXT_NULL__;
@@ -47,20 +47,20 @@ static const struct mesh MESH_NULL = {NULL, NULL, 0, 0};
/*******************************************************************************
* Helper functions
******************************************************************************/
-/* Check that `hit' roughly lies on an edge. For triangular primitives, a
- * simple but approximative way is to test that its position have at least one
- * barycentric coordinate roughly equal to 0 or 1. */
+/* Check that the barycentric coordinates defines a position near of an edge.
+ * To do so test that at least one barycentric coordinate is roughly equal to 0
+ * or 1. */
static FINLINE int
-hit_on_edge(const struct s3d_hit* hit)
+is_on_edge(const float uv[2])
{
const float on_edge_eps = 1.e-4f;
float w;
- ASSERT(hit && !S3D_HIT_NONE(hit));
- w = 1.f - hit->uv[0] - hit->uv[1];
- return eq_epsf(hit->uv[0], 0.f, on_edge_eps)
- || eq_epsf(hit->uv[0], 1.f, on_edge_eps)
- || eq_epsf(hit->uv[1], 0.f, on_edge_eps)
- || eq_epsf(hit->uv[1], 1.f, on_edge_eps)
+ ASSERT(uv);
+ w = 1.f - uv[0] - uv[1];
+ return eq_epsf(uv[0], 0.f, on_edge_eps)
+ || eq_epsf(uv[0], 1.f, on_edge_eps)
+ || eq_epsf(uv[1], 0.f, on_edge_eps)
+ || eq_epsf(uv[1], 1.f, on_edge_eps)
|| eq_epsf(w, 0.f, on_edge_eps)
|| eq_epsf(w, 1.f, on_edge_eps);
}
@@ -73,23 +73,22 @@ self_hit
const float ray_org[3],
const float ray_dir[3],
const float ray_range[2],
- const struct s3d_hit* hit_from)
+ const struct sgs_s3d_position* pos_from)
{
- ASSERT(hit && hit_from);
+ ASSERT(hit && pos_from);
(void)ray_org, (void)ray_dir, (void)ray_range;
- /* The hit primitive is the one from which the the ray starts. Discard these
- * hits */
- if(S3D_PRIMITIVE_EQ(&hit->prim, &hit_from->prim))
+ /* The hit primitive is the one from which the the ray starts. Discard it */
+ if(S3D_PRIMITIVE_EQ(&hit->prim, &pos_from->prim))
return 1;
/* If the targeted point is near of the origin, check that it lies on an
* edge/vertex shared by the 2 primitives. In such situation, we assume that
* it is a self intersection and discard this hit */
- if(!S3D_HIT_NONE(hit_from)
+ if(!S3D_PRIMITIVE_EQ(&pos_from->prim, &S3D_PRIMITIVE_NULL)
&& eq_epsf(hit->distance, 0, 1.e-1f)
- && hit_on_edge(hit_from)
- && hit_on_edge(hit)) {
+ && is_on_edge(pos_from->st)
+ && is_on_edge(hit->uv)) {
return 1;
}
@@ -117,7 +116,7 @@ hit_filter
if(hit->distance <= ctx->range[0] || hit->distance >= ctx->range[1])
return 1;
- if(self_hit(hit, ray_org, ray_dir, ctx->range, &ctx->hit_from))
+ if(self_hit(hit, ray_org, ray_dir, ctx->range, &ctx->pos_from))
return 1; /* Discard this hit */
return 0; /* No filtering */
@@ -231,14 +230,15 @@ sgs_geometry_trace_ray
const double ray_org[3],
const double ray_dir[3],
const double ray_range[2],
- const struct s3d_hit* hit_from,
- struct s3d_hit* hit)
+ const struct sgs_s3d_position* pos_from,
+ struct sgs_hit* out_hit)
{
struct hit_filter_context filter_ctx = HIT_FILTER_CONTEXT_NULL;
+ struct s3d_hit hit = S3D_HIT_NULL;
float org[3];
float dir[3];
float range[2];
- ASSERT(geom && ray_org && ray_dir && ray_range && hit);
+ ASSERT(geom && ray_org && ray_dir && ray_range && out_hit);
/* Convert ray data to single precision */
f3_set_d3(org, ray_org);
@@ -252,10 +252,22 @@ sgs_geometry_trace_ray
/* Setup the hit filter data */
filter_ctx.range[0] = range[0];
filter_ctx.range[1] = range[1];
- filter_ctx.hit_from = hit_from ? *hit_from : S3D_HIT_NULL;
+ filter_ctx.pos_from = pos_from ? *pos_from : SGS_S3D_POSITION_NULL;
/* Trace the ray */
- S3D(scene_view_trace_ray(geom->view_rt, org, dir, range, &filter_ctx, hit));
+ S3D(scene_view_trace_ray(geom->view_rt, org, dir, range, &filter_ctx, &hit));
+
+ /* Setup the output hit */
+ *out_hit = SGS_HIT_NULL;
+ if(!S3D_HIT_NONE(&hit)) {
+ d3_set_f3(out_hit->normal, hit.normal);
+ d3_normalize(out_hit->normal, out_hit->normal);
+ out_hit->distance = hit.distance;
+ out_hit->surface_type = darray_int_cdata_get(&geom->tris_type)[hit.prim.prim_id];
+ out_hit->s3d_pos.prim = hit.prim;
+ out_hit->s3d_pos.st[0] = hit.uv[0];
+ out_hit->s3d_pos.st[1] = hit.uv[1];
+ }
}
res_T
diff --git a/src/sgs_geometry.h b/src/sgs_geometry.h
@@ -20,6 +20,7 @@
#ifndef SGS_GEOMETRY_H
#define SGS_GEOMETRY_H
+#include <star/s3d.h>
#include <rsys/rsys.h>
enum sgs_geometry_type {
@@ -114,6 +115,42 @@ struct sgs_geometry_step_args {
static const struct sgs_geometry_step_args SGS_GEOMETRY_STEP_ARGS_DEFAULT =
SGS_GEOMETRY_STEP_ARGS_DEFAULT__;
+/* Position defined relatively to a Star-3D primitive */
+struct sgs_s3d_position {
+ struct s3d_primitive prim;
+ float st[2]; /* Parametric coordinates onto the primitive */
+};
+#define SGS_S3D_POSITION_NULL__ {S3D_PRIMITIVE_NULL__, {0,0}}
+static const struct sgs_s3d_position SGS_S3D_POSITION_NULL =
+ SGS_S3D_POSITION_NULL__;
+
+/* Position onto a geometry surface */
+struct sgs_fragment {
+ double normal[3]; /* Normalized */
+ double position[3];
+ enum sgs_surface_type surface_type;
+
+ /* Position defined wrt the corresponding Star-3D primitive */
+ struct sgs_s3d_position s3d_pos;
+};
+#define SGS_FRAGMENT_NULL__ {{0,0,0},{0,0,0},0,SGS_S3D_POSITION_NULL__}
+static const struct sgs_fragment SGS_FRAGMENT_NULL = SGS_FRAGMENT_NULL__;
+
+/* Intersection along a ray */
+struct sgs_hit {
+ double normal[3]; /* Normalized */
+ double distance; /* Distance up to the intersection */
+ enum sgs_surface_type surface_type;
+
+ /* Position defined wrt the corresponding Star-3D primitive */
+ struct sgs_s3d_position s3d_pos;
+};
+#define SGS_HIT_NULL__ {{0,0,0},DBL_MAX,0,SGS_S3D_POSITION_NULL__}
+static const struct sgs_hit SGS_HIT_NULL = SGS_HIT_NULL__;
+
+/* Helper macro */
+#define SGS_HIT_NONE(Hit) ((Hit)->distance >= FLT_MAX)
+
/* Forward declaration */
struct s3d_hit;
struct sgs;
@@ -154,8 +191,8 @@ sgs_geometry_trace_ray
const double ray_org[3],
const double ray_dir[3],
const double ray_range[2],
- const struct s3d_hit* hit_from, /* May be NULL */
- struct s3d_hit* hit);
+ const struct sgs_s3d_position* pos_from, /* To avoid self hit. May be NULL */
+ struct sgs_hit* hit);
extern LOCAL_SYM res_T
sgs_geometry_dump_vtk