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 1e1facbf1e6a0727360be5241f00e465c3de1795
parent 9a9a0c47a132f0c28c6bfce1094684104b0bb97d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 15 Sep 2015 16:14:38 +0200

Add and test the "scene space" primitive identifier

Diffstat:
Msrc/s3d.h | 5+++--
Msrc/s3d_geometry.h | 1+
Msrc/s3d_scene.c | 46++++++++++++++++++++++++++++++++++++----------
Msrc/test_s3d_sampler.c | 6++++--
Msrc/test_s3d_scene.c | 1+
Msrc/test_s3d_trace_ray.c | 3+++
6 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/src/s3d.h b/src/s3d.h @@ -98,13 +98,14 @@ struct s3d_primitive { unsigned prim_id; /* Primitive identifier */ unsigned geom_id; /* Geometry identifier */ unsigned inst_id; /* Instance identifier */ + unsigned scene_prim_id; /* Identifier of the primitive in the scene */ /* Internal data. Should not be accessed */ void* mesh__; void* inst__; }; static const struct s3d_primitive S3D_PRIMITIVE_NULL = { - S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, NULL, NULL + S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, NULL, NULL }; /* Helper macro that defines whether or not 2 primites are equal */ @@ -149,7 +150,7 @@ struct s3d_hit { /* Constant defining a NULL intersection. Should be used to initialize a hit */ static const struct s3d_hit S3D_HIT_NULL = { - { S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, NULL, NULL }, + { S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, NULL, NULL }, { 0.f, 0.f, 0.f }, { 0.f, 0.f }, FLT_MAX diff --git a/src/s3d_geometry.h b/src/s3d_geometry.h @@ -47,6 +47,7 @@ enum geometry_type { struct geometry { unsigned name; /* Client side identifier */ unsigned irtc; /* Embree identifier */ + unsigned scene_prim_id_offset; /* Offset from local to scene prim_id */ char flip_surface; /* Is the geometry surface flipped? */ char is_enabled; /* Is the geometry enabled? */ diff --git a/src/s3d_scene.c b/src/s3d_scene.c @@ -396,11 +396,13 @@ error: static FINLINE bool operator < (const struct fltui& it, const float val) { - return it.flt <= val; /* TODO commen the <= */ + return it.flt <= val; /* TODO comment the <= */ } static res_T -scene_compute_nprims_cdf(struct s3d_scene* scn) +scene_compute_nprims_cdf + (struct s3d_scene* scn, + const char store_cdf) { struct list_node* node; struct s3d_shape* shape; @@ -423,13 +425,14 @@ scene_compute_nprims_cdf(struct s3d_scene* scn) if(!geom->is_enabled) continue; + geom->scene_prim_id_offset = nprims; switch(geom->type) { case GEOM_MESH: len = mesh_get_ntris(geom->data.mesh); nprims += (unsigned)len; break; case GEOM_INSTANCE: - res = scene_compute_nprims_cdf(geom->data.instance->scene); + res = scene_compute_nprims_cdf(geom->data.instance->scene, store_cdf); if(res != RES_OK) goto error; len = darray_nprims_cdf_size_get(&geom->data.instance->scene->nprims_cdf); if(len) { @@ -442,7 +445,7 @@ scene_compute_nprims_cdf(struct s3d_scene* scn) cdf.nprims = nprims; cdf.irtc = geom->irtc; - if(len) { + if(store_cdf && len) { res = darray_nprims_cdf_push_back(&scn->nprims_cdf, &cdf); if(res != RES_OK) goto error; } @@ -507,9 +510,12 @@ scene_sync(struct s3d_scene* scn, const int session_mask) if(res != RES_OK) goto error; } if((session_mask & S3D_GET_PRIMITIVE) != 0) { - res = scene_compute_nprims_cdf(scn); - if(res != RES_OK) goto error; + res = scene_compute_nprims_cdf(scn, 1); + } else { + res = scene_compute_nprims_cdf(scn, 0); } + if(res != RES_OK) goto error; + if((session_mask & S3D_TRACE) != 0 && scn->is_rtc_scn_outdated) { rtcCommit(scn->rtc_scn); scn->is_rtc_scn_outdated = 0; @@ -780,23 +786,35 @@ s3d_scene_trace_ray hit->uv[0] = w; if((unsigned)ray.instID == RTC_INVALID_GEOMETRY_ID) { + struct geometry* geom_mesh; ASSERT((unsigned)ray.geomID < darray_geom_size_get(&scn->embree2geoms)); - hit->prim.mesh__ = darray_geom_data_get(&scn->embree2geoms)[ray.geomID]; + geom_mesh = darray_geom_data_get(&scn->embree2geoms)[ray.geomID]; + hit->prim.mesh__ = geom_mesh; hit->prim.inst__ = NULL; hit->prim.prim_id = ray.primID; - hit->prim.geom_id = ((struct geometry*)hit->prim.mesh__)->name; + hit->prim.geom_id = geom_mesh->name; hit->prim.inst_id = S3D_INVALID_ID; + hit->prim.scene_prim_id = /* Compute the "scene space" primitive id */ + hit->prim.prim_id /* Mesh space */ + + geom_mesh->scene_prim_id_offset; /* Scene space */ } else { /* The hit shape is instantiated */ /* Retrieve the hit instance */ struct geometry* geom_inst; + struct geometry* geom_mesh; ASSERT((unsigned)ray.instID < darray_geom_size_get(&scn->embree2geoms)); geom_inst = darray_geom_data_get(&scn->embree2geoms)[ray.instID]; - hit->prim.mesh__ = scene_get_mesh(geom_inst->data.instance->scene, ray.geomID); + geom_mesh = scene_get_mesh(geom_inst->data.instance->scene, ray.geomID); + hit->prim.mesh__ = geom_mesh; hit->prim.inst__ = geom_inst; hit->prim.prim_id = ray.primID; - hit->prim.geom_id = ((struct geometry*)hit->prim.mesh__)->name; + hit->prim.geom_id = geom_mesh->name; hit->prim.inst_id = geom_inst->name; + hit->prim.scene_prim_id = /* Compute the "scene space" */ + hit->prim.prim_id /* Mesh space */ + + geom_mesh->scene_prim_id_offset /* Inst space */ + + geom_inst->scene_prim_id_offset; /* Scene space */ + flip_surface = geom_inst->flip_surface; ASSERT(hit->prim.inst__); ASSERT(((struct geometry*)hit->prim.inst__)->type == GEOM_INSTANCE); @@ -901,11 +919,13 @@ s3d_scene_sample if(geom->type == GEOM_MESH) { primitive->inst__ = NULL; primitive->inst_id = S3D_INVALID_ID; + primitive->scene_prim_id = 0; } else { /* Find the sampled instantiated geometry */ ASSERT(geom->type == GEOM_INSTANCE); primitive->inst__ = geom; primitive->inst_id = geom->name; + primitive->scene_prim_id = geom->scene_prim_id_offset; if(darray_fltui_size_get(&geom->data.instance->scene->cdf) == 1) { igeom = darray_fltui_cdata_get(&geom->data.instance->scene->cdf)[0].ui; } else { @@ -928,12 +948,14 @@ s3d_scene_sample /* Find the sampled triangle */ primitive->mesh__ = geom; primitive->geom_id = geom->name; + primitive->scene_prim_id += geom->scene_prim_id_offset; flt_begin = darray_float_cdata_get(&geom->data.mesh->cdf); flt_end = flt_begin + darray_float_size_get(&geom->data.mesh->cdf); flt_found = std::lower_bound(flt_begin, flt_end, f); ASSERT(flt_found != flt_end); primitive->prim_id = (unsigned)(flt_found - flt_begin); + primitive->scene_prim_id += primitive->prim_id; S3D(primitive_sample(primitive, v, w, st)); exit: @@ -987,10 +1009,12 @@ s3d_scene_get_primitive if(geom->type == GEOM_MESH) { prim->inst__ = NULL; prim->inst_id = S3D_INVALID_ID; + prim->scene_prim_id = 0; } else { ASSERT(geom->type == GEOM_INSTANCE); prim->inst__ = geom; prim->inst_id = geom->name; + prim->scene_prim_id = geom->scene_prim_id_offset; if(darray_nprims_cdf_size_get(&geom->data.instance->scene->nprims_cdf)==1) { igeom = darray_nprims_cdf_cdata_get (&geom->data.instance->scene->nprims_cdf)[0].irtc; @@ -1016,6 +1040,8 @@ s3d_scene_get_primitive prim->mesh__ = geom; prim->geom_id = geom->name; prim->prim_id = (unsigned)i; + prim->scene_prim_id += geom->scene_prim_id_offset; + prim->scene_prim_id += prim->prim_id; exit: return res; diff --git a/src/test_s3d_sampler.c b/src/test_s3d_sampler.c @@ -204,8 +204,10 @@ main(int argc, char** argv) CHECK(prim.geom_id == walls_id || prim.geom_id == tall_block_id || prim.geom_id == short_block_id, 1); - CHECK(prim.geom_id < 10, 1); - printf("%f %f %f\n", SPLIT3(attr0.value)); + CHECK(prim.prim_id < 10, 1); + CHECK(prim.scene_prim_id >= prim.prim_id, 1); + CHECK(prim.scene_prim_id < 30, 1); +/* printf("%f %f %f\n", SPLIT3(attr0.value)); */ } CHECK(s3d_scene_end_session(scn2), RES_OK); diff --git a/src/test_s3d_scene.c b/src/test_s3d_scene.c @@ -270,6 +270,7 @@ main(int argc, char** argv) size_t j; CHECK(s3d_scene_get_primitive(scn2, (unsigned)i, prims + i), RES_OK); CHECK(S3D_PRIMITIVE_EQ(prims + i, &S3D_PRIMITIVE_NULL), 0); + CHECK(prims[i].scene_prim_id, i); FOR_EACH(j, 0, i) CHECK(S3D_PRIMITIVE_EQ(prims + i, prims + j), 0); } diff --git a/src/test_s3d_trace_ray.c b/src/test_s3d_trace_ray.c @@ -311,6 +311,9 @@ main(int argc, char** argv) f3_normalize(attr.value, attr.value); CHECK(f3_eq_eps(attr.value, N, 1.e-6f), 1); + CHECK(hit.prim.scene_prim_id >= hit.prim.prim_id, 1); + CHECK(hit.prim.scene_prim_id < 30, 1); + if(!img) continue;