commit 0b3a64e9f6af41c7cbc3cc6c8b66c7dc3526f4e8
parent 51affe8d794d8cb51bb6878c6065fec392f16bfc
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 6 Feb 2018 11:47:35 +0100
Add the htvox_scene_get_voxels_count function
Diffstat:
3 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/src/htvox.h b/src/htvox.h
@@ -97,6 +97,11 @@ htvox_scene_ref_put
(struct htvox_scene* scn);
HTVOX_API res_T
+htvox_scene_get_voxels_count
+ (const struct htvox_scene* scn,
+ size_t* nvoxels);
+
+HTVOX_API res_T
htvox_scene_get_aabb
(const struct htvox_scene* scn,
double lower[3],
diff --git a/src/htvox_scene.c b/src/htvox_scene.c
@@ -48,6 +48,7 @@ struct octree_builder {
void* context; /* Client side data sent to the merge callback */
int octree_depth;
uint64_t mcode; /* Morton code of the last registered voxels */
+ size_t nvoxels; /* Number of voxels, i.e. leaves, */
};
/*******************************************************************************
@@ -138,12 +139,14 @@ static res_T
stack_write
(struct stack* stack, /* Node to write */
struct octree_buffer* buffer, /* Buffer where nodes are written */
- struct octree_index* out_index) /* Index of the first written node */
+ struct octree_index* out_index, /* Index of the first written node */
+ size_t* nvoxels) /* Number of written voxels */
{
- struct octree_index nodes_id;
+ struct octree_index nodes_id = OCTREE_INDEX_NULL;
+ size_t nvoxs = 0;
int inode;
res_T res = RES_OK;
- ASSERT(stack && buffer && out_index);
+ ASSERT(stack && buffer && out_index && nvoxels);
/* No registered nodes <=> nodes were merged in an higher level */
if(!stack->len) goto exit;
@@ -158,6 +161,7 @@ stack_write
if(res != RES_OK) goto error;
xnodes = octree_buffer_get_node(buffer, nodes_id);
+ nvoxs = 0;
FOR_EACH(inode, 0, stack->len) {
struct octree_node* node = stack->nodes + inode;
size_t offset = SIZE_MAX;
@@ -169,13 +173,14 @@ stack_write
double* leaf;
/* Alloc the leaf node */
- ASSERT(OCTREE_INDEX_EQ(&node->ichildren, &OCTREE_INDEX_NULL));
res = octree_buffer_alloc_leaves(buffer, 1, &node->ichildren);
if(res != RES_OK) goto error;
/* Setup the leaf data */
leaf = octree_buffer_get_leaf(buffer, node->ichildren);
*leaf = node->data;
+
+ nvoxs += 1;
}
/* Define the offset toward the children of the current node */
@@ -210,10 +215,11 @@ stack_write
}
} while(inode < stack->len);
- /* Return the index toward the first writen nodes */
- *out_index = nodes_id;
exit:
+ /* Return the index toward the first writen nodes */
+ *out_index = nodes_id;
+ *nvoxels = nvoxs;
return res;
error:
goto exit;
@@ -248,6 +254,7 @@ octree_builder_init
bldr->merge = merge;
bldr->context = context;
bldr->buffer = buffer;
+ bldr->nvoxels = 0;
exit:
return res;
@@ -256,7 +263,9 @@ error:
}
static res_T
-octree_builder_add_voxel(struct octree_builder* bldr, const struct voxel* vox)
+octree_builder_add_voxel
+ (struct octree_builder* bldr,
+ const struct voxel* vox)
{
uint64_t mcode_xor;
res_T res = RES_OK;
@@ -275,6 +284,7 @@ octree_builder_add_voxel(struct octree_builder* bldr, const struct voxel* vox)
* the voxels and can be skipped */
FOR_EACH(ilvl, 0, bldr->octree_depth-1/*The last level contain all voxels*/) {
struct octree_node* stack_node;
+ size_t nvoxels;
uint64_t mcode_max_lvl;
/* Compute the maximum morton code value for the current octree level */
@@ -292,9 +302,12 @@ octree_builder_add_voxel(struct octree_builder* bldr, const struct voxel* vox)
ASSERT(bldr->stacks[ilvl+1].len <= 8);
/* Write the nodes of the stack of the current octree level into the buf */
- res = stack_write(&bldr->stacks[ilvl], bldr->buffer, &stack_node->ichildren);
+ res = stack_write
+ (&bldr->stacks[ilvl], bldr->buffer, &stack_node->ichildren, &nvoxels);
if(res != RES_OK) goto error;
+ bldr->nvoxels += nvoxels;
+
/* Reset the current stack */
stack_clear(&bldr->stacks[ilvl]);
}
@@ -318,6 +331,7 @@ octree_builder_finalize
(struct octree_builder* bldr,
struct octree_index* root_id)
{
+ size_t nvoxels;
int ilvl;
res_T res = RES_OK;
ASSERT(bldr);
@@ -337,16 +351,21 @@ octree_builder_finalize
bldr->stacks[ilvl+1].len += 1;
/* Write the stacked nodes of the current level */
- res = stack_write(&bldr->stacks[ilvl], bldr->buffer, &parent_node->ichildren);
+ res = stack_write
+ (&bldr->stacks[ilvl], bldr->buffer, &parent_node->ichildren, &nvoxels);
if(res != RES_OK) goto error;
+
+ bldr->nvoxels += nvoxels;
}
ASSERT(bldr->stacks[bldr->octree_depth-1].len == 1);
/* Write the root node */
ilvl = bldr->octree_depth-1; /* Root level */
- res = stack_write(&bldr->stacks[ilvl], bldr->buffer, root_id);
+ res = stack_write(&bldr->stacks[ilvl], bldr->buffer, root_id, &nvoxels);
if(res != RES_OK) goto error;
+ bldr->nvoxels += nvoxels;
+
exit:
return res;
error:
@@ -478,6 +497,8 @@ htvox_scene_create
res = octree_builder_finalize(&bldr, &scn->root);
if(res != RES_OK) goto error;
+ scn->nvoxels = bldr.nvoxels;
+
#ifndef NDEBUG
check_octree(&scn->buffer, scn->root);
#endif
diff --git a/src/htvox_scene.h b/src/htvox_scene.h
@@ -22,6 +22,7 @@
struct htvox_scene {
double vox_scale[3]; /* Scale factor of the octree */
size_t definition; /* Definition of the octree */
+ size_t nvoxels; /* Overall #voxels effectively stored in the octree */
double lower[3], upper[3]; /* World space AABB of the scene */
double oclow[3], ocupp[3]; /* World space AABB of the octree */