commit 3d6f5bd34402a9cbf1ecefd479c47e6df772593f
parent 59831938eed74e099aaedc84004084fdd79e0b99
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 27 Feb 2018 15:31:47 +0100
Make the voxel data "generic"
The caller can now define the size of the voxel. This size could be at
most equal to the constant HTVOX_MAX_SIZEOF_VOXEL.
Diffstat:
5 files changed, 197 insertions(+), 85 deletions(-)
diff --git a/src/htvox.h b/src/htvox.h
@@ -37,16 +37,51 @@
#define HTVOX(Func) htvox_ ## Func
#endif
+/* Maximum memory size of a voxel */
+#define HTVOX_MAX_SIZEOF_VOXEL (sizeof(double)*16)
+
struct htvox_voxel {
- double data; /* Data of the voxel */
+ const void* data; /* Data of the voxel */
size_t id; /* Indentifier of the voxel */
};
-#define HTVOX_VOXEL_NULL__ { DBL_MAX, SIZE_MAX }
+#define HTVOX_VOXEL_NULL__ { NULL, SIZE_MAX }
static const struct htvox_voxel HTVOX_VOXEL_NULL = HTVOX_VOXEL_NULL__;
#define HTVOX_VOXEL_NONE(Voxel) ((Voxel)->id == HTVOX_VOXEL_NULL.id)
+/* Descriptor of a voxel */
+struct htvox_voxel_desc {
+ /* Retrieve the data of the voxels*/
+ void
+ (*get)
+ (const size_t xyz[3], /* Voxel coordinate in voxel space */
+ void* dst, /* Where to store data */
+ void* ctx); /* Pointer toward user data */
+
+ /* Merge the data of N voxels */
+ void
+ (*merge)
+ (void* dst, /* Merged data */
+ const void* voxels[], /* Data to merge */
+ const size_t nvoxels, /* #submitted data */
+ void* ctx); /* Pointer toward user data */
+
+ /* Check if the voxel's data can be merged */
+ int
+ (*challenge_merge)
+ (const void* voxels[], /* Data candidates to the merge */
+ const size_t nvoxels, /* #candidates */
+ void* ctx); /* Pointer toward user data */
+
+ void* context; /* Client side data sent as the last argument of the clbbs */
+ size_t size; /* Size in bytes of a voxel. Must be <= HTVOX_MAX_SIZEOF_VOXE */
+};
+
+#define HTVOX_VOXEL_DESC_NULL__ { NULL, NULL, NULL, NULL, 0 }
+static const struct htvox_voxel_desc HTVOX_VOXEL_DESC_NULL =
+ HTVOX_VOXEL_DESC_NULL__;
+
struct htvox_hit {
double distance; /* Distance from the ray origin to the impacted voxel */
struct htvox_voxel voxel; /* Intersected voxel */
@@ -94,9 +129,7 @@ htvox_scene_create
const double lower[3], /* Lower bound of the scene */
const double upper[3], /* Upper bound of the scene */
const size_t nvoxels[3], /* # voxels along the 3 axis */
- void (*get)(const size_t xyz[3], double* value, void* ctx),
- int (*merge)(const double min_val, const double max_val, void* ctx),
- void* context, /* Client data sent as the last param of the callbacks */
+ const struct htvox_voxel_desc* desc, /* Descriptor of a voxel */
struct htvox_scene** scn);
HTVOX_API res_T
@@ -122,11 +155,11 @@ HTVOX_API res_T
htvox_scene_for_each_voxel
(struct htvox_scene* scn,
void (*functor)
- (const double val, /* Value of the voxel */
- const size_t ivoxel, /* Identifier of the voxel */
- const double low[3], /* World space lower bound of the voxel */
- const double upp[3], /* World space upper bound of the voxel */
- void* ctx), /* Client data */
+ (const void* val, /* Value of the voxel */
+ const size_t ivoxel, /* Identifier of the voxel */
+ const double low[3], /* World space lower bound of the voxel */
+ const double upp[3], /* World space upper bound of the voxel */
+ void* ctx), /* Client data */
void* context); /* Client data sent as the last argument of the callback */
HTVOX_API res_T
diff --git a/src/htvox_octree_buffer.c b/src/htvox_octree_buffer.c
@@ -64,7 +64,7 @@ ensure_allocated_leaves(struct octree_buffer* buf, const size_t nleaves)
ASSERT(buf);
if(buf->leaf_head.ipage != OCTREE_INDEX_NULL.ipage
- && buf->leaf_head.inode + nleaves <= buf->pagesize/sizeof(double))
+ && buf->leaf_head.inode + nleaves <= buf->pagesize/buf->voxsize)
goto exit;
nleaf_pages = darray_page_size_get(&buf->leaf_pages);
@@ -92,16 +92,21 @@ error:
* Local functions
******************************************************************************/
void
-octree_buffer_init(struct mem_allocator* allocator, struct octree_buffer* buf)
+octree_buffer_init
+ (struct mem_allocator* allocator,
+ const size_t voxel_size,
+ struct octree_buffer* buf)
{
ASSERT(buf && allocator);
memset(buf, 0, sizeof(struct octree_buffer));
buf->pagesize = (size_t)sysconf(_SC_PAGESIZE);
+ buf->voxsize = voxel_size;
darray_page_init(allocator, &buf->node_pages);
darray_page_init(allocator, &buf->leaf_pages);
buf->node_head = OCTREE_INDEX_NULL;
buf->leaf_head = OCTREE_INDEX_NULL;
buf->allocator = allocator;
+ CHK(buf->voxsize <= buf->pagesize);
}
void
@@ -141,7 +146,7 @@ octree_buffer_alloc_leaves
res_T res = RES_OK;
ASSERT(buf && first_leaf);
- if(nleaves >= buf->pagesize / sizeof(double)) return RES_MEM_ERR;
+ if(nleaves >= buf->pagesize / buf->voxsize) return RES_MEM_ERR;
res = ensure_allocated_leaves(buf, nleaves);
if(res != RES_OK) return res;
diff --git a/src/htvox_octree_buffer.h b/src/htvox_octree_buffer.h
@@ -47,7 +47,7 @@ struct octree_xnode {
uint16_t node_offset;
uint16_t leaf_offset;
uint8_t is_valid; /* Mask defining if the children are valid */
- uint8_t is_leaf; /* Mask defining if the children are leafs */
+ uint8_t is_leaf; /* Mask defining if the children are leaves */
uint16_t dummy__; /* Ensure that the size of the node is 8 bytes */
};
@@ -72,6 +72,7 @@ static const struct octree_index OCTREE_INDEX_NULL = OCTREE_INDEX_NULL__;
struct octree_buffer {
size_t pagesize; /* Memory page size in bytes */
+ size_t voxsize; /* Memory size of a voxel in bytes */
struct darray_page node_pages; /* List of pages storing nodes */
struct darray_page leaf_pages; /* List of pages storing leaves */
@@ -84,6 +85,7 @@ struct octree_buffer {
extern LOCAL_SYM void
octree_buffer_init
(struct mem_allocator* allocator,
+ const size_t sizeof_voxel, /* Size in bytes of a voxel */
struct octree_buffer* buf);
extern LOCAL_SYM void
@@ -147,17 +149,17 @@ octree_buffer_get_far_index
return (struct octree_index*)mem;
}
-static FINLINE double*
+static FINLINE void*
octree_buffer_get_leaf
(struct octree_buffer* buf,
- const struct octree_index id)
+ const struct octree_index id)
{
char* mem;
- ASSERT(buf && id.inode < buf->pagesize/sizeof(double));
+ ASSERT(buf && id.inode < buf->pagesize/buf->voxsize);
ASSERT(id.ipage < darray_page_size_get(&buf->leaf_pages));
mem = darray_page_data_get(&buf->leaf_pages)[id.ipage];
- mem += id.inode * sizeof(double);
- return (double*)mem;
+ mem += id.inode * buf->voxsize;
+ return mem;
}
static FINLINE struct octree_index
diff --git a/src/htvox_scene.c b/src/htvox_scene.c
@@ -25,15 +25,16 @@
struct voxel {
uint64_t mcode; /* Morton code of the voxel */
- double data; /* Data of the voxel */
+ void* data; /* Data of the voxel */
};
+static const struct voxel VOXEL_NULL = {0, NULL};
struct octree_node {
struct octree_index ichild_node; /* Index of the 1st child node */
struct octree_index ichild_leaf; /* Index of the 1st child leaf */
uint8_t is_valid; /* Mask defining whether the children are valid or not */
uint8_t is_leaf; /* Mask defining whether the children are leaves or not */
- double data[8]; /* Data of the leaves */
+ ALIGN(16) char data[8][HTVOX_MAX_SIZEOF_VOXEL]; /* Data of the leaves */
};
/* Stacked children of an octree node */
@@ -46,9 +47,7 @@ struct octree_builder {
struct stack stacks[OCTREE_DEPTH_MAX];
struct octree_buffer* buffer;
- int (*merge)(const double min_val, const double max_val, void* ctx);
- void* context; /* Client side data sent to the merge callback */
-
+ const struct htvox_voxel_desc* desc;
int octree_depth;
uint64_t mcode; /* Morton code of the last registered voxels */
@@ -83,6 +82,17 @@ check_octree(struct octree_buffer* buf, const struct octree_index root)
}
#endif
+static INLINE int
+check_htvox_voxel_desc(const struct htvox_voxel_desc* desc)
+{
+ return desc
+ && desc->get
+ && desc->merge
+ && desc->challenge_merge
+ && desc->size > 0
+ && desc->size <= HTVOX_MAX_SIZEOF_VOXEL;
+}
+
static INLINE void
stack_clear(struct stack* stack)
{
@@ -94,7 +104,7 @@ stack_clear(struct stack* stack)
stack->nodes[inode].ichild_node = OCTREE_INDEX_NULL;
stack->nodes[inode].ichild_leaf = OCTREE_INDEX_NULL;
FOR_EACH(ileaf, 0, 8) {
- stack->nodes[inode].data[ileaf] = 0;
+ memset(stack->nodes[inode].data[ileaf], 0, HTVOX_MAX_SIZEOF_VOXEL);
}
}
stack->mask = 0;
@@ -105,11 +115,10 @@ static INLINE void
stack_setup_node
(struct stack* stack,
struct octree_node* node,
- int (*merge_func)(const double min_val, const double max_val, void* ctx),
- void* context)
+ const struct htvox_voxel_desc* desc)
{
int ichild;
- ASSERT(stack && node && merge_func);
+ ASSERT(stack && node && check_htvox_voxel_desc(desc));
node->ichild_node = OCTREE_INDEX_NULL;
node->ichild_leaf = OCTREE_INDEX_NULL;
@@ -120,8 +129,7 @@ stack_setup_node
/* Try to merge the child's leaves */
FOR_EACH(ichild, 0, 8) {
- double data_min = DBL_MAX;
- double data_max =-DBL_MAX;
+ const void* data[8];
struct octree_node* child = stack->nodes + ichild;
int ileaf;
@@ -130,13 +138,13 @@ stack_setup_node
/* Find the minimum and maximum of the leaves */
FOR_EACH(ileaf, 0, 8) {
- data_min = MMIN(child->data[ileaf], data_min);
- data_max = MMAX(child->data[ileaf], data_max);
+ data[ileaf] = child->data[ileaf];
}
+
/* Challenge the merge function */
- if(merge_func(data_min, data_max, context)) {
+ if(desc->challenge_merge(data, 8, desc->context)) {
const uint8_t ichild_flag = (uint8_t)BIT(ichild);
- node->data[ichild] = data_max;
+ desc->merge(node->data[ichild], data, 8, desc->context);
node->is_leaf |= ichild_flag;
/* The node does not exist anymore in the stack since it became a leaf
@@ -165,7 +173,7 @@ stack_write
/* Write the leaves */
FOR_EACH(inode, 0, 8) {
size_t nleaves;
- double* leaves;
+ char* leaves;
size_t nvoxs_node;
int ileaf;
@@ -182,7 +190,11 @@ stack_write
leaves = octree_buffer_get_leaf(buffer, node->ichild_leaf);
nvoxs_node = 0;
FOR_EACH(ileaf, 0, 8) {
- if(node->is_leaf & BIT(ileaf)) leaves[nvoxs_node++] = node->data[ileaf];
+ if(node->is_leaf & BIT(ileaf)) {
+ memcpy(leaves + nvoxs_node*buffer->voxsize, node->data[ileaf],
+ buffer->voxsize);
+ ++nvoxs_node;
+ }
}
ASSERT(nvoxs_node == nleaves);
}
@@ -263,13 +275,12 @@ static res_T
octree_builder_init
(struct octree_builder* bldr,
const size_t definition,
- int (*merge)(const double min_val, const double max_val, void* ctx),
- void* context,
+ const struct htvox_voxel_desc* desc,
struct octree_buffer* buffer)
{
int ilvl;
res_T res = RES_OK;
- ASSERT(bldr && IS_POW2(definition) && merge);
+ ASSERT(bldr && IS_POW2(definition) && check_htvox_voxel_desc(desc));
memset(bldr, 0, sizeof(struct octree_builder));
/* Compute the maximum depth of the octree */
@@ -285,8 +296,7 @@ octree_builder_init
}
octree_buffer_clear(buffer);
- bldr->merge = merge;
- bldr->context = context;
+ bldr->desc = desc;
bldr->buffer = buffer;
exit:
@@ -337,8 +347,7 @@ octree_builder_add_voxel
/* The next voxel is not in the ilvl^th stack. Setup the parent node of the
* nodes registered into the stack */
stack_node = &bldr->stacks[ilvl+1].nodes[inode];
- stack_setup_node
- (&bldr->stacks[ilvl], stack_node, bldr->merge, bldr->context);
+ stack_setup_node(&bldr->stacks[ilvl], stack_node, bldr->desc);
bldr->stacks[ilvl+1].mask |= (uint8_t)BIT(inode);
/* Write the nodes of the stack of the current octree level into the buf */
@@ -357,7 +366,7 @@ octree_builder_add_voxel
ichild_flag = (uint8_t)BIT(ichild);
/* Register the voxel */
- bldr->stacks[0].nodes[inode].data[ichild] = vox->data;
+ memcpy(bldr->stacks[0].nodes[inode].data[ichild], vox->data, bldr->desc->size);
bldr->stacks[0].nodes[inode].is_valid |= ichild_flag;
bldr->stacks[0].nodes[inode].is_leaf |= ichild_flag;
@@ -394,8 +403,7 @@ octree_builder_finalize
/* Setup the parent node of the nodes registered into the current stack */
parent_node = &bldr->stacks[ilvl+1].nodes[inode]; /* Fetch the parent node */
- stack_setup_node
- (&bldr->stacks[ilvl], parent_node, bldr->merge, bldr->context);
+ stack_setup_node(&bldr->stacks[ilvl], parent_node, bldr->desc);
bldr->stacks[ilvl+1].mask |= (uint8_t)BIT(inode);
/* Write the stacked nodes of the current level */
@@ -437,19 +445,19 @@ htvox_scene_create
const double lower[3], /* Lower bound of the scene */
const double upper[3], /* Upper bound of the scene */
const size_t nvoxels[3], /* # voxels along the 3 axis */
- void (*get)(const size_t xyz[3], double* value, void* ctx),
- int (*merge)(const double min_val, const double max_val, void* ctx),
- void* context, /* Client data send as the last param of the `get' callback */
+ const struct htvox_voxel_desc* desc, /* Descriptor of a voxel */
struct htvox_scene** out_scn)
{
struct htvox_scene* scn = NULL;
double vox_sz[3]; /* World space size of a voxel */
struct octree_builder bldr;
+ struct voxel vox = VOXEL_NULL;
uint64_t mcode_max;
uint64_t mcode;
res_T res = RES_OK;
- if(!dev || !lower || !upper || !nvoxels || !get || !merge || !out_scn) {
+ if(!dev || !lower || !upper || !nvoxels
+ || !check_htvox_voxel_desc(desc) || !out_scn) {
res = RES_BAD_ARG;
goto error;
}
@@ -481,7 +489,7 @@ htvox_scene_create
}
ref_init(&scn->ref);
HTVOX(device_ref_get(dev));
- octree_buffer_init(dev->allocator, &scn->buffer);
+ octree_buffer_init(dev->allocator, desc->size, &scn->buffer);
scn->dev = dev;
/* Compute the octree definition */
@@ -491,13 +499,17 @@ htvox_scene_create
scn->definition = round_up_pow2(scn->definition);
/* Intialize the octree builder */
- res = octree_builder_init
- (&bldr, scn->definition, merge, context, &scn->buffer);
+ res = octree_builder_init(&bldr, scn->definition, desc, &scn->buffer);
if(res != RES_OK) goto error;
+ vox.data = MEM_CALLOC(dev->allocator, 1, desc->size);
+ if(!vox.data) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
mcode_max = scn->definition * scn->definition * scn->definition;
FOR_EACH(mcode, 0, mcode_max) {
- struct voxel vox;
size_t xyz[3];
uint32_t ui3[3];
@@ -513,7 +525,7 @@ htvox_scene_create
xyz[0] = (size_t)ui3[0];
xyz[1] = (size_t)ui3[1];
xyz[2] = (size_t)ui3[2];
- get(xyz, &vox.data, context);
+ desc->get(xyz, vox.data, desc->context);
vox.mcode = mcode;
/* Register the voxel against the octree */
@@ -543,6 +555,7 @@ htvox_scene_create
scn->ocupp[2] = (double)scn->definition * vox_sz[2];
exit:
+ if(vox.data) MEM_RM(dev->allocator, vox.data);
if(out_scn) *out_scn = scn;
return res;
error:
@@ -598,7 +611,7 @@ res_T
htvox_scene_for_each_voxel
(struct htvox_scene* scn,
void (*func)
- (const double val,
+ (const void* val,
const size_t ivoxel,
const double low[3],
const double upp[3],
@@ -655,10 +668,10 @@ htvox_scene_for_each_voxel
if(node->is_leaf & ichild_flag) {
struct octree_index ileaf;
size_t ivoxel;
- double val;
+ const void* val;
ileaf = octree_buffer_get_leaf_index(&scn->buffer, entry.inode, ichild);
- val = *octree_buffer_get_leaf(&scn->buffer, ileaf);
+ val = octree_buffer_get_leaf(&scn->buffer, ileaf);
ASSERT(upp[0] <= scn->upper[0]);
ASSERT(upp[1] <= scn->upper[1]);
@@ -747,7 +760,7 @@ htvox_scene_at
break;
} else if(node->is_leaf & ichild_flag) { /* Leaf node */
inode = octree_buffer_get_leaf_index(&scn->buffer, inode, ichild);
- voxel->data = *octree_buffer_get_leaf(&scn->buffer, inode);
+ voxel->data = octree_buffer_get_leaf(&scn->buffer, inode);
voxel->id =
inode.ipage * scn->buffer.pagesize / sizeof(double) + inode.inode;
break;
diff --git a/src/test_htvox_scene.c b/src/test_htvox_scene.c
@@ -26,26 +26,58 @@ struct check_context {
};
static int
-no_merge(const double min_val, const double max_val, void* ctx)
+no_merge(const void* voxels[], const size_t nvoxels, void* ctx)
{
- CHK(min_val <= max_val);
+ CHK(voxels != NULL);
+ CHK(nvoxels != 0);
CHK((intptr_t)ctx == 0xDECAFBAD);
return 0; /* Merge nothing */
}
static int
-merge_level0(const double min_val, const double max_val, void* ctx)
+merge_level0(const void** voxels, const size_t nvoxels, void* ctx)
{
- CHK(min_val <= max_val);
+ double min_val = DBL_MAX;
+ double max_val =-DBL_MAX;
+ size_t i;
+ CHK(voxels != NULL);
+ CHK(nvoxels != 0);
CHK((intptr_t)ctx == 0xDECAFBAD);
+
+ FOR_EACH(i, 0, nvoxels) {
+ const double* val = voxels[i];
+ min_val = MMIN(min_val, *val);
+ max_val = MMAX(max_val, *val);
+ }
+
return (max_val - min_val) < 8;
}
static void
-get(const size_t xyz[3], double* val, void* ctx)
+keep_max(void* dst, const void* voxels[], const size_t nvoxels, void* ctx)
+{
+ double* vox_dst = dst;
+ double max_val = -DBL_MAX;
+ size_t i;
+
+ CHK(dst != NULL);
+ CHK(voxels != NULL);
+ CHK(nvoxels != 0);
+ CHK(ctx != NULL);
+
+ FOR_EACH(i, 0, nvoxels) {
+ const double* val = voxels[i];
+ max_val = MMAX(max_val, *val);
+ }
+ *vox_dst = max_val;
+}
+
+static void
+get(const size_t xyz[3], void* dst, void* ctx)
{
uint32_t ui3[3];
uint64_t mcode;
+ double* val = dst;
CHK(xyz != NULL);
CHK(val != NULL);
CHK((intptr_t)ctx == 0xDECAFBAD);
@@ -60,19 +92,20 @@ get(const size_t xyz[3], double* val, void* ctx)
static void
check_voxel
- (const double val,
+ (const void* val,
const size_t ivoxel,
const double low[3],
const double upp[3],
void* context)
{
+ const double* dbl = val;
struct check_context* ctx = context;
uint64_t mcode;
uint32_t xyz[3];
double lower[3];
double delta[3];
- CHK(val >= 0);
+ CHK(val != NULL);
CHK(low != NULL);
CHK(upp != NULL);
CHK(ctx != NULL);
@@ -80,9 +113,10 @@ check_voxel
CHK(low[1] < upp[1]);
CHK(low[2] < upp[2]);
CHK(ivoxel < ctx->nvoxels[0]*ctx->nvoxels[1]*ctx->nvoxels[2]);
+ CHK(*dbl >= 0);
- mcode = (uint64_t)val;
- CHK(val == (double)mcode);
+ mcode = (uint64_t)(*dbl);
+ CHK(*dbl == (double)mcode);
delta[0] = (ctx->upper[0] - ctx->lower[0]) / (double)ctx->nvoxels[0];
delta[1] = (ctx->upper[1] - ctx->lower[1]) / (double)ctx->nvoxels[1];
@@ -103,7 +137,7 @@ check_voxel
static void
write_points
- (const double val,
+ (const void* val,
const size_t ivoxel,
const double low[3],
const double upp[3],
@@ -129,7 +163,7 @@ write_points
static void
write_cells
- (const double val,
+ (const void* val,
const size_t ivoxel,
const double low[3],
const double upp[3],
@@ -153,7 +187,7 @@ write_cells
static void
write_scalars
- (const double val,
+ (const void* val,
const size_t ivoxel,
const double low[3],
const double upp[3],
@@ -164,7 +198,7 @@ write_scalars
CHK(stream != NULL);
CHK(low != NULL);
CHK(upp != NULL);
- fprintf(stream, "%g\n", val);
+ fprintf(stream, "%g\n", *(double*)val);
}
static void
@@ -205,6 +239,7 @@ main(int argc, char** argv)
struct htvox_device* dev = NULL;
struct htvox_scene* scn = NULL;
struct mem_allocator allocator;
+ struct htvox_voxel_desc desc = HTVOX_VOXEL_DESC_NULL;
double low[3];
double upp[3];
double pos[3];
@@ -230,7 +265,12 @@ main(int argc, char** argv)
#define NEW_SCN htvox_scene_create
- CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_OK);
+ desc.get = get;
+ desc.merge = keep_max;
+ desc.challenge_merge = no_merge;
+ desc.context = ptr;
+ desc.size = sizeof(double);
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_OK);
CHK(htvox_scene_ref_get(NULL) == RES_BAD_ARG);
CHK(htvox_scene_ref_get(scn) == RES_OK);
@@ -239,22 +279,40 @@ main(int argc, char** argv)
CHK(htvox_scene_ref_put(scn) == RES_OK);
upp[0] = low[0];
- CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG);
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
upp[0] = 1.0;
nvxls[2] = 0;
- CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG);
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
nvxls[2] = nvxls[0];
- CHK(NEW_SCN(NULL, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG);
- CHK(NEW_SCN(dev, NULL, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG);
- CHK(NEW_SCN(dev, low, NULL, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG);
- CHK(NEW_SCN(dev, low, upp, NULL, get, no_merge, ptr, &scn) == RES_BAD_ARG);
- CHK(NEW_SCN(dev, low, upp, nvxls, NULL, no_merge, ptr, &scn) == RES_BAD_ARG);
- CHK(NEW_SCN(dev, low, upp, nvxls, get, NULL, ptr, &scn) == RES_BAD_ARG);
- CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, NULL) == RES_BAD_ARG);
+ CHK(NEW_SCN(NULL, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
+ CHK(NEW_SCN(dev, NULL, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
+ CHK(NEW_SCN(dev, low, NULL, nvxls, &desc, &scn) == RES_BAD_ARG);
+ CHK(NEW_SCN(dev, low, upp, NULL, &desc, &scn) == RES_BAD_ARG);
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, NULL) == RES_BAD_ARG);
+
+ desc.get = NULL;
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
+ desc.get = get;
+
+ desc.merge = NULL;
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
+ desc.merge = keep_max;
+
+ desc.challenge_merge = NULL;
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
+ desc.challenge_merge = no_merge;
+
+ desc.size = 0;
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
+ desc.size = sizeof(double);
+
+ desc.size = HTVOX_MAX_SIZEOF_VOXEL + 1;
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_BAD_ARG);
+ desc.size = sizeof(double);
- CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_OK);
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_OK);
CHK(htvox_scene_for_each_voxel(scn, check_voxel, &ctx) == RES_OK);
@@ -286,7 +344,7 @@ main(int argc, char** argv)
CHK(!HTVOX_VOXEL_NONE(&vox));
mcode = morton_xyz_encode_u21(ui3);
- CHK(vox.data == mcode);
+ CHK(*((double*)vox.data) == mcode);
}
}
}
@@ -303,7 +361,8 @@ main(int argc, char** argv)
CHK(htvox_scene_ref_put(scn) == RES_OK);
nvxls[0] = nvxls[1] = nvxls[2] = 8;
- CHK(NEW_SCN(dev, low, upp, nvxls, get, merge_level0, ptr, &scn) == RES_OK);
+ desc.challenge_merge = merge_level0;
+ CHK(NEW_SCN(dev, low, upp, nvxls, &desc, &scn) == RES_OK);
CHK(htvox_scene_get_voxels_count(scn, &nvoxels) == RES_OK);
CHK(nvoxels == nvxls[0]*nvxls[1]*nvxls[2] / 8);