star-3d

Surface structuring for efficient 3D geometric queries
git clone git://git.meso-star.fr/star-3d.git
Log | Files | Refs | README | LICENSE

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:
Msrc/s3d.h | 3++-
Msrc/s3d_scene.c | 30+++++++++++++++++++++++++++---
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; }