star-vx

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

commit c4fc8b85361ac902d5dd7741e0c2f9b016441b03
parent 9c11749ab9ad18b91a459dbe46ef920a55201985
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 10 May 2018 13:41:34 +0200

Test the at accessor of the binary tree

Diffstat:
Msrc/svx.h | 14++++++++++++--
Msrc/svx_tree.c | 3+++
Msrc/svx_tree_generic_func.h | 2+-
Msrc/test_svx_bintree.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/test_svx_octree.c | 4+++-
5 files changed, 103 insertions(+), 8 deletions(-)

diff --git a/src/svx.h b/src/svx.h @@ -112,10 +112,20 @@ struct svx_tree_desc { size_t depth; /* Depth of the octree */ enum svx_tree_type type; + + /* Define the axis in world space along which the tree is defined. In 1D, + * (i.e. bintree) only the first component of the frame is defined while in + * 3D (i.e. octree), the 3 components is always defined to SVX_AXIS_X, + * SVX_AXIS_Y and SVX_AXYS_Z. */ + enum svx_axis frame[3]; }; -#define SVX_TREE_DESC_NULL__ \ - {{DBL_MAX, DBL_MAX, DBL_MAX}, {-DBL_MAX,-DBL_MAX,-DBL_MAX}, 0, 0, 0, 0} +#define SVX_TREE_DESC_NULL__ { \ + { DBL_MAX, DBL_MAX, DBL_MAX}, \ + {-DBL_MAX,-DBL_MAX,-DBL_MAX}, \ + 0, 0, 0, 0, \ + {SVX_AXIS_NONE__, SVX_AXIS_NONE__, SVX_AXIS_NONE__} \ +} static const struct svx_tree_desc SVX_TREE_DESC_NULL = SVX_TREE_DESC_NULL__; diff --git a/src/svx_tree.c b/src/svx_tree.c @@ -75,6 +75,9 @@ svx_tree_get_desc (&tree->buffer, tree->buffer.attr_head) + 1; /* Root node */ desc->depth = tree->depth; desc->type = tree->type; + desc->frame[0] = tree->frame[0]; + desc->frame[1] = tree->frame[1]; + desc->frame[2] = tree->frame[2]; return RES_OK; } diff --git a/src/svx_tree_generic_func.h b/src/svx_tree_generic_func.h @@ -163,7 +163,7 @@ TREE_FUNC(at) /* Transform the position in the normalized octree space, * i.e. octree lies in [0, 1]^2 */ pos[i] = (position[tree->frame[i]] - tree->tree_low[tree->frame[i]]) - / tree->tree_size[i]; + / tree->tree_size[tree->frame[i]]; /* Initialized the lower left corner of the current node */ low[i] = 0; } diff --git a/src/test_svx_bintree.c b/src/test_svx_bintree.c @@ -18,6 +18,8 @@ #include "test_svx_utils.h" #include <rsys/math.h> +#define AXIS SVX_AXIS_Y + struct leaves_context { double lower; double upper; @@ -29,6 +31,11 @@ struct leaves_context { size_t nleaves; }; +struct at_context { + double position; + size_t depth; +}; + static void get(const size_t xyz[3], void* dst, void* ctx) { @@ -36,7 +43,7 @@ get(const size_t xyz[3], void* dst, void* ctx) CHK(xyz != NULL); CHK(val != NULL); CHK((intptr_t)ctx == 0xDECAFBAD); - *val = (double)xyz[SVX_AXIS_Y]; + *val = (double)xyz[AXIS]; } static int @@ -67,6 +74,21 @@ keep_max(void* dst, const void* voxels[], const size_t nvoxels, void* ctx) *vox_dst = max_val; } +static int +max_lod + (const struct svx_voxel* vox, + const double pos[3], + void* context) +{ + const struct at_context* ctx = context; + CHK(vox != NULL); + CHK(pos != NULL); + CHK(ctx != NULL); + CHK(vox->depth <= ctx->depth); + CHK(pos[AXIS] == ctx->position); + return vox->depth < ctx->depth; +} + static void check_leaves (const struct svx_voxel* leaf, @@ -99,6 +121,62 @@ check_leaves ctx->nleaves += 1; } +static void +test_at_accessor(struct svx_tree* tree, const size_t nvoxels) +{ + struct svx_tree_desc desc; + struct at_context ctx; + size_t nvxls; + double tree_sz; + double delta; + enum svx_axis axis; + + CHK(svx_tree_get_desc(tree, &desc) == RES_OK); + CHK(desc.type == SVX_BINTREE); + CHK(desc.frame[0] = AXIS); + + axis = desc.frame[0]; + tree_sz = desc.upper[axis] - desc.lower[axis]; + delta = tree_sz / (double)nvoxels; + + ctx.depth = desc.depth; + CHK(ctx.depth > 0); + + nvxls = nvoxels; + + /* TODO Comment this */ + while(ctx.depth-- != 0) { + double pos[3] = {0, 0, 0}; + const size_t iter = desc.depth - ctx.depth - 1; + size_t i; + + FOR_EACH(i, 0, nvxls) { + struct svx_voxel vox; + const double low = desc.lower[axis] + (double)i * delta; + const double upp = low + delta; + size_t mcode; + + pos[axis] = desc.lower[axis] + ((double)i+1.0/(1u<<(2+iter)))*delta; + + ctx.position = pos[axis]; + CHK(svx_tree_at(tree, pos, max_lod, &ctx, &vox) == RES_OK); + + mcode = i * (1u<<iter) + ((1u << iter) - 1); + mcode = MMIN(mcode, nvoxels-1); + + CHK(*((double*)vox.data) == mcode); + CHK(vox.is_leaf == (desc.depth-1 == ctx.depth)); + CHK(vox.depth == ctx.depth); + CHK(eq_eps(vox.lower[axis], low, 1.e-6)); + CHK(eq_eps(vox.upper[axis], upp, 1.e-6)); + } + + nvxls = nvxls == 1 ? 0 : (nvxls + 1/*ceil*/)/2; + delta = MMIN(delta * 2, tree_sz); + } + CHK(nvxls == 0); +} + int main(int argc, char** argv) { @@ -119,7 +197,7 @@ main(int argc, char** argv) low = 0.0; upp = 1.0; - axis = SVX_AXIS_Y; + axis = AXIS; nvxls = 5; vox_desc.get = get; @@ -159,7 +237,7 @@ main(int argc, char** argv) axis = SVX_AXIS_NONE__; CHK(NEW_TREE(dev, low, upp, nvxls, axis, &vox_desc, &tree) == RES_BAD_ARG); - axis = SVX_AXIS_Y; + axis = AXIS; CHK(NEW_TREE(NULL, low, upp, nvxls, axis, &vox_desc, &tree) == RES_BAD_ARG); CHK(NEW_TREE(dev, low, upp, nvxls, axis, NULL, &tree) == RES_BAD_ARG); @@ -170,7 +248,7 @@ main(int argc, char** argv) ctx.upper = upp; ctx.nvoxels = nvxls; ctx.depth = 4; - ctx.axis = SVX_AXIS_Y; + ctx.axis = AXIS; ctx.nleaves = 0; CHK(ctx.leaves = MEM_CALLOC(&allocator, 5, 1)); @@ -188,6 +266,8 @@ main(int argc, char** argv) CHK(tree_desc.lower[axis] == low); CHK(tree_desc.upper[axis] == upp); + test_at_accessor(tree, nvxls); + #undef NEW_SCN CHK(svx_tree_ref_put(tree) == RES_OK); diff --git a/src/test_svx_octree.c b/src/test_svx_octree.c @@ -170,7 +170,6 @@ max_lod return vox->depth < ctx->depth; } - static void test_at_accessor(struct svx_tree* oct, const size_t nvoxels[3]) { @@ -184,6 +183,9 @@ test_at_accessor(struct svx_tree* oct, const size_t nvoxels[3]) CHK(nvoxels != NULL); CHK(svx_tree_get_desc(oct, &tree_desc) == RES_OK); CHK(tree_desc.type == SVX_OCTREE); + CHK(tree_desc.frame[0] == SVX_AXIS_X); + CHK(tree_desc.frame[1] == SVX_AXIS_Y); + CHK(tree_desc.frame[2] == SVX_AXIS_Z); ocsz[0] = tree_desc.upper[0] - tree_desc.lower[0]; ocsz[1] = tree_desc.upper[1] - tree_desc.lower[1];