star-vx

Structuring voxels for ray-tracing
git clone git://git.meso-star.fr/star-vx.git
Log | Files | Refs | README | LICENSE

commit 4ca88b445120404bb44cf628f03546e91ef7a72c
parent b34fd4f29e4024a842ce444d8dfbefd8caea3033
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 11 Jan 2021 13:35:01 +0100

Update the API of the get functor of the voxel descriptor

Add the Morton code of the voxel as input parameter

Diffstat:
Msrc/svx.h | 5++++-
Msrc/svx_bintree.c | 2+-
Msrc/svx_octree.c | 2+-
Msrc/test_svx_bintree.c | 6++++--
Msrc/test_svx_bintree_trace_ray.c | 3++-
Msrc/test_svx_octree.c | 17+++++++++++++----
Msrc/test_svx_octree_trace_ray.c | 9++++++++-
7 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/src/svx.h b/src/svx.h @@ -74,10 +74,13 @@ static const struct svx_voxel SVX_VOXEL_NULL = SVX_VOXEL_NULL__; /* Descriptor of a voxel */ struct svx_voxel_desc { - /* Retrieve the data of the voxels*/ + /* Retrieve the data of the voxels. Star-VoXel ensures that the Voxels are + * accessed according to the morton order where Z vary priorly to Y and Y + * priorly to X. */ void (*get) (const size_t xyz[3], /* Voxel coordinate in voxel space */ + const uint64_t mcode, /* Morton code of the voxel */ void* dst, /* Where to store data */ void* ctx); /* Pointer toward user data */ diff --git a/src/svx_bintree.c b/src/svx_bintree.c @@ -102,7 +102,7 @@ svx_bintree_create /* Retrieve the voxel data from the caller */ xyz[axis] = ivox; - desc->get(xyz, vox.data, desc->context); + desc->get(xyz, ivox, vox.data, desc->context); vox.mcode = ivox; /* Register the voxel against the bintree */ diff --git a/src/svx_octree.c b/src/svx_octree.c @@ -136,7 +136,7 @@ svx_octree_create xyz[0] = (size_t)ui3[0]; xyz[1] = (size_t)ui3[1]; xyz[2] = (size_t)ui3[2]; - desc->get(xyz, vox.data, desc->context); + desc->get(xyz, mcode, vox.data, desc->context); vox.mcode = mcode; /* Register the voxel against the octree */ diff --git a/src/test_svx_bintree.c b/src/test_svx_bintree.c @@ -52,12 +52,13 @@ struct build_context { static void -get(const size_t xyz[3], void* dst, void* ctx) +get(const size_t xyz[3], const uint64_t mcode, void* dst, void* ctx) { double* val = dst; CHK(xyz != NULL); CHK(val != NULL); CHK((intptr_t)ctx == 0xDECAFBAD); + CHK(mcode == xyz[AXIS]); *val = (double)xyz[AXIS]; } @@ -137,11 +138,12 @@ check_leaves } static void -get_aabb(const size_t xyz[3], void* dst, void* ctx) +get_aabb(const size_t xyz[3], const uint64_t mcode, void* dst, void* ctx) { const struct build_context* build_ctx = ctx; struct aabb* aabb = dst; + CHK(mcode == xyz[AXIS]); d3_splat(aabb->lower,-INF); d3_splat(aabb->upper, INF); aabb->lower[AXIS] = diff --git a/src/test_svx_bintree_trace_ray.c b/src/test_svx_bintree_trace_ray.c @@ -39,7 +39,7 @@ rand_canonic(void) } static void -voxel_get(const size_t xyz[3], void* dst, void* ctx) +voxel_get(const size_t xyz[3], const uint64_t mcode, void* dst, void* ctx) { const struct scene* scn = ctx; char* val = dst; @@ -50,6 +50,7 @@ voxel_get(const size_t xyz[3], void* dst, void* ctx) CHK(xyz != NULL); CHK(dst != NULL); CHK(ctx != NULL); + CHK(mcode == xyz[scn->axis]); /* Compute the range of the voxel */ low = (double)xyz[scn->axis] * scn->vxsz + scn->origin; diff --git a/src/test_svx_octree.c b/src/test_svx_octree.c @@ -101,10 +101,9 @@ keep_max(void* dst, const void* voxels[], const size_t nvoxels, void* ctx) } static void -get(const size_t xyz[3], void* dst, void* ctx) +get(const size_t xyz[3], const uint64_t mcode, void* dst, void* ctx) { uint32_t ui3[3]; - uint64_t mcode; double* val = dst; CHK(xyz != NULL); CHK(val != NULL); @@ -114,7 +113,11 @@ get(const size_t xyz[3], void* dst, void* ctx) ui3[1] = (uint32_t)xyz[1]; ui3[2] = (uint32_t)xyz[2]; - mcode = morton_xyz_encode_u21(ui3); + CHK(mcode == morton_xyz_encode_u21(ui3)); + CHK(mcode == + ( morton3D_encode_u21(ui3[0]) << 2 + | morton3D_encode_u21(ui3[1]) << 1 + | morton3D_encode_u21(ui3[2]) << 0)); *val = (double)mcode; } @@ -193,14 +196,20 @@ max_lod } static void -get_aabb(const size_t xyz[3], void* dst, void* ctx) +get_aabb(const size_t xyz[3], const uint64_t mcode, void* dst, void* ctx) { const struct build_context* build_ctx = ctx; struct aabb* aabb = dst; + uint32_t ui3[3]; aabb->lower[0] = (double)xyz[0] * build_ctx->voxsz[0] + build_ctx->lower[0]; aabb->lower[1] = (double)xyz[1] * build_ctx->voxsz[1] + build_ctx->lower[1]; aabb->lower[2] = (double)xyz[2] * build_ctx->voxsz[2] + build_ctx->lower[2]; + + ui3[0] = (uint32_t)xyz[0]; + ui3[1] = (uint32_t)xyz[1]; + ui3[2] = (uint32_t)xyz[2]; + CHK(mcode == morton_xyz_encode_u21(ui3)); d3_add(aabb->upper, aabb->lower, build_ctx->voxsz); aabb->depth = build_ctx->max_depth; } diff --git a/src/test_svx_octree_trace_ray.c b/src/test_svx_octree_trace_ray.c @@ -26,6 +26,7 @@ #include <rsys/double3.h> #include <rsys/image.h> #include <rsys/math.h> +#include <rsys/morton.h> struct scene { double origin[3]; @@ -59,12 +60,13 @@ sphere_intersect_aabb } static void -voxel_get(const size_t xyz[3], void* dst, void* ctx) +voxel_get(const size_t xyz[3], const uint64_t mcode, void* dst, void* ctx) { const struct scene* scn = ctx; char* val = dst; double low[3]; double upp[3]; + uint32_t ui3[3]; CHK(xyz != NULL); CHK(dst != NULL); CHK(ctx != NULL); @@ -77,6 +79,11 @@ voxel_get(const size_t xyz[3], void* dst, void* ctx) upp[1] = low[1] + scn->vxsz[1]; upp[2] = low[2] + scn->vxsz[2]; + ui3[0] = (uint32_t)xyz[0]; + ui3[1] = (uint32_t)xyz[1]; + ui3[2] = (uint32_t)xyz[2]; + CHK(mcode == morton_xyz_encode_u21(ui3)); + /* Binary octree, i.e. it stores if the voxel intersect the sphere or not */ *val = sphere_intersect_aabb(scn->sphere_pos, scn->sphere_radius, low, upp); }