commit 438589f90f9a70244659ece9d03a823e6441e0c2
parent 4202e4dc49a3d0ebe652afd36b6af35d36ac6c00
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 20 Mar 2015 12:21:29 +0100
Fix instantiation support in the s3d_scene_trace ray function
Diffstat:
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/src/s3d.h b/src/s3d.h
@@ -108,6 +108,7 @@ static const struct s3d_vertex_data S3D_VERTEX_DATA_NULL =
/* Intersection point */
struct s3d_hit {
struct s3d_shape* shape; /* Hit shape */
+ struct s3d_scene* scene; /* Hit scene */
unsigned iprim; /* Index of the intersected primitive */
float normal[3]; /* Unormalized geometry normal */
float uv[2]; /* Barycentric coordinates of the hit onto `iprim' */
@@ -116,7 +117,7 @@ struct s3d_hit {
/* Constant defining a NULL intersection. Should be used to initialize a hit */
static const struct s3d_hit S3D_HIT_NULL =
-{NULL, 0, {0.f,0.f,0.f}, {0.f,0.f}, FLT_MAX};
+{NULL, NULL, 0, {0.f,0.f,0.f}, {0.f,0.f}, FLT_MAX};
/* Helper macro that defines whether or not the hit is valid, i.e. the ray
* intersects a shape or not */
diff --git a/src/s3d_scene.c b/src/s3d_scene.c
@@ -426,9 +426,33 @@ s3d_scene_trace_ray
hit->uv[1] = ray.v;
hit->distance = ray.tfar;
hit->iprim = ray.primID;
- ASSERT((unsigned)ray.geomID < darray_geom2shape_size_get(&scn->geom2shape));
- hit->shape = darray_geom2shape_data_get(&scn->geom2shape)[ray.geomID];
- ASSERT(hit->shape != NULL && (unsigned)ray.geomID == hit->shape->rtc_geom);
+
+ if((unsigned)ray.instID == RTC_INVALID_GEOMETRY_ID) {
+ ASSERT((unsigned)ray.geomID
+ < darray_geom2shape_size_get(&scn->geom2shape));
+ hit->shape = darray_geom2shape_data_get
+ (&scn->geom2shape)[ray.geomID];
+ ASSERT(hit->shape != NULL && (unsigned)ray.geomID == hit->shape->rtc_geom);
+ ASSERT(hit->shape->type == SHAPE_MESH);
+ hit->scene = scn;
+ } else { /* The hit shape is instantiated */
+ /* Retrieve the hit instance */
+ ASSERT((unsigned)ray.instID
+ < darray_geom2shape_size_get(&scn->geom2shape));
+ hit->shape = darray_geom2shape_data_get
+ (&scn->geom2shape)[ray.instID];
+ ASSERT(hit->shape != NULL && (unsigned)ray.instID == hit->shape->rtc_geom);
+ ASSERT(hit->shape->type == SHAPE_INSTANCE);
+ hit->scene = hit->shape->data.instance.scene;
+
+ /* Retrieve the hit geometry into the instance */
+ ASSERT((unsigned)ray.geomID
+ < darray_geom2shape_size_get(&hit->scene->geom2shape));
+ hit->shape = darray_geom2shape_data_get
+ (&hit->scene->geom2shape)[ray.geomID];
+ ASSERT(hit->shape != NULL && (unsigned)ray.geomID == hit->shape->rtc_geom);
+ ASSERT(hit->shape->type == SHAPE_MESH);
+ }
}
return RES_OK;
}