commit 727196b479f34c0f139fd5eb712b36410bdbd094
parent 8f1c0b37afd1174191fc01ed02d0830cf281f1d4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 7 Mar 2018 16:03:22 +0100
Test the voxel AABB returned by svx_octree_at
Diffstat:
2 files changed, 64 insertions(+), 23 deletions(-)
diff --git a/src/svx_octree.c b/src/svx_octree.c
@@ -728,6 +728,7 @@ svx_octree_at
double scale_exp2;
double low[3];
double pos[3];
+ double ocsz[3]; /* Octree size along the 3 axis */
res_T res = RES_OK;
if(!oct || !position || !voxel) {
@@ -744,11 +745,15 @@ svx_octree_at
goto exit;
}
+ ocsz[0] = oct->ocupp[0] - oct->oclow[0];
+ ocsz[1] = oct->ocupp[1] - oct->oclow[1];
+ ocsz[2] = oct->ocupp[2] - oct->oclow[2];
+
/* Transform the position in the normalized octree space,
* i.e. octree lies in [0, 1]^2 */
- pos[0] = (position[0] - oct->oclow[0]) / (oct->ocupp[0] - oct->oclow[0]);
- pos[1] = (position[1] - oct->oclow[1]) / (oct->ocupp[1] - oct->oclow[1]);
- pos[2] = (position[2] - oct->oclow[2]) / (oct->ocupp[2] - oct->oclow[2]);
+ pos[0] = (position[0] - oct->oclow[0]) / ocsz[0];
+ pos[1] = (position[1] - oct->oclow[1]) / ocsz[1];
+ pos[2] = (position[2] - oct->oclow[2]) / ocsz[2];
/* Initialized the lower left corner of the current node */
low[0] = 0;
@@ -758,6 +763,8 @@ svx_octree_at
/* Root voxel */
vox.depth = 0;
vox.is_leaf = 0;
+ d3_set(vox.lower, oct->lower);
+ d3_set(vox.upper, oct->upper);
if(filter) {
vox.data = oct->root_attr;
vox.id = absolute_attr_index(&oct->buffer, oct->buffer.attr_head);
@@ -792,9 +799,18 @@ svx_octree_at
vox.is_leaf = (node->is_leaf & ichild_flag) != 0;
if(filter || vox.is_leaf) {
iattr = octree_buffer_get_child_attr_index(&oct->buffer, inode, ichild);
+
+ /* Setup the voxel */
+ vox.lower[0] = low[0] * ocsz[0] + oct->oclow[0];
+ vox.lower[1] = low[1] * ocsz[1] + oct->oclow[1];
+ vox.lower[2] = low[2] * ocsz[2] + oct->oclow[2];
+ vox.upper[0] = vox.lower[0] + ocsz[0] * scale_exp2;
+ vox.upper[1] = vox.lower[1] + ocsz[1] * scale_exp2;
+ vox.upper[2] = vox.lower[2] + ocsz[2] * scale_exp2;
vox.data = octree_buffer_get_attr(&oct->buffer, iattr);
vox.id = absolute_attr_index(&oct->buffer, iattr);
vox.is_leaf = (node->is_leaf & ichild_flag) != 0;
+
if(vox.is_leaf || !filter(&vox, position, context)) {
*voxel = vox;
break;
diff --git a/src/test_svx_octree.c b/src/test_svx_octree.c
@@ -19,13 +19,18 @@
#include <rsys/double3.h>
-struct check_context {
+struct leaves_context {
double* lower;
double* upper;
size_t* nvoxels;
size_t depth;
};
+struct at_context {
+ double position[3];
+ size_t depth;
+};
+
static int
no_merge(const void* voxels[], const size_t nvoxels, void* ctx)
{
@@ -98,7 +103,7 @@ check_leaves
void* context)
{
const double* dbl = NULL;
- struct check_context* ctx = context;
+ struct leaves_context* ctx = context;
uint64_t mcode;
uint32_t xyz[3];
double lower[3];
@@ -229,15 +234,15 @@ static int
max_lod
(const struct svx_voxel* vox,
const double pos[3],
- void* ctx)
+ void* context)
{
- size_t* pdepth = ctx;
-
+ const struct at_context* ctx = context;
CHK(vox != NULL);
CHK(pos != NULL);
CHK(ctx != NULL);
- CHK(vox->depth <= *pdepth);
- return vox->depth < *pdepth;
+ CHK(vox->depth <= ctx->depth);
+ CHK(d3_eq(pos, ctx->position));
+ return vox->depth < ctx->depth;
}
@@ -245,34 +250,46 @@ static void
test_at_accessor(struct svx_octree* oct, const size_t nvoxels[3])
{
struct svx_octree_desc octdesc;
+ struct at_context ctx;
size_t nvxls;
- double pos[3];
double delta[3];
- size_t depth;
+ double ocsz[3];
size_t x, y, z;
CHK(nvoxels != NULL);
CHK(svx_octree_get_desc(oct, &octdesc) == RES_OK);
- delta[0] = (octdesc.upper[0] - octdesc.lower[0])/(double)nvoxels[0];
- delta[1] = (octdesc.upper[1] - octdesc.lower[1])/(double)nvoxels[1];
- delta[2] = (octdesc.upper[2] - octdesc.lower[2])/(double)nvoxels[2];
+ ocsz[0] = octdesc.upper[0] - octdesc.lower[0];
+ ocsz[1] = octdesc.upper[1] - octdesc.lower[1];
+ ocsz[2] = octdesc.upper[2] - octdesc.lower[2];
+ delta[0] = ocsz[0]/(double)nvoxels[0];
+ delta[1] = ocsz[1]/(double)nvoxels[1];
+ delta[2] = ocsz[2]/(double)nvoxels[2];
nvxls = nvoxels[0];
nvxls = MMAX(nvxls, nvoxels[1]);
nvxls = MMAX(nvxls, nvoxels[2]);
- depth = octdesc.depth;
+ ctx.depth = octdesc.depth;
+ CHK(ctx.depth > 0);
- while(depth-- != 0) {
- const size_t iter = octdesc.depth - depth - 1;
+ while(ctx.depth-- != 0) {
+ const size_t iter = octdesc.depth - ctx.depth - 1;
+ double pos[3];
+ double low[3];
+ double upp[3];
FOR_EACH(x, 0, nvxls) {
pos[0] = octdesc.lower[0] + ((double)x+1.0/(1u<<(2+iter)))*delta[0];
+ low[0] = octdesc.lower[0] + (double)x * delta[0];
+ upp[0] = low[0] + delta[0];
if(x*(1u<<iter) >= nvoxels[0]) break;
FOR_EACH(y, 0, nvxls) {
pos[1] = octdesc.lower[1] + ((double)y+1.0/(1u<<(2+iter)))*delta[1];
+ low[1] = octdesc.lower[1] + (double)y * delta[1];
+ upp[1] = low[1] + delta[1];
+
if(y*(1u<<iter) >= nvoxels[1]) break;
FOR_EACH(z, 0, nvxls) {
@@ -281,9 +298,13 @@ test_at_accessor(struct svx_octree* oct, const size_t nvoxels[3])
uint64_t mcode;
pos[2] = octdesc.lower[2] + ((double)z+1.0/(1u<<(2+iter)))*delta[2];
+ low[2] = octdesc.lower[2] + (double)z * delta[2];
+ upp[2] = low[2] + delta[2];
+
if(z*(1u<<iter) >= nvoxels[2]) break;
- CHK(svx_octree_at(oct, pos, max_lod, &depth, &vox) == RES_OK);
+ d3_set(ctx.position, pos);
+ CHK(svx_octree_at(oct, pos, max_lod, &ctx, &vox) == RES_OK);
CHK(!SVX_VOXEL_NONE(&vox));
ui3[0] = (uint32_t)x * (1u << iter) + ((1u << iter) - 1);
@@ -295,14 +316,18 @@ test_at_accessor(struct svx_octree* oct, const size_t nvoxels[3])
mcode = morton_xyz_encode_u21(ui3);
CHK(*((double*)vox.data) == mcode);
- CHK(vox.is_leaf == (octdesc.depth-1==depth));
- CHK(vox.depth == depth);
+ CHK(vox.is_leaf == (octdesc.depth-1==ctx.depth));
+ CHK(vox.depth == ctx.depth);
+ CHK(d3_eq_eps(vox.lower, low, 1.e-6));
+ CHK(d3_eq_eps(vox.upper, upp, 1.e-6));
}
}
}
nvxls = nvxls == 1 ? 0 : (nvxls + 1/*ceil*/) / 2;
- d3_muld(delta, delta, 2);
+ delta[0] = MMIN(delta[0] * 2, ocsz[0]);
+ delta[1] = MMIN(delta[1] * 2, ocsz[1]);
+ delta[2] = MMIN(delta[2] * 2, ocsz[2]);
}
CHK(nvxls == 0);
}
@@ -318,7 +343,7 @@ main(int argc, char** argv)
double low[3];
double upp[3];
size_t nvxls[3];
- struct check_context ctx;
+ struct leaves_context ctx;
void* ptr = (void*)0xDECAFBAD;
(void)argc, (void)argv;