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:
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;