star-vx

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

commit 91b1381d6b978f013543e5329adf6faec4c2424e
parent 9c6537cbdee20b55e9a1683b6b11e4125c6632d4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  6 Feb 2018 12:43:35 +0100

Implement the htvox_scene_at function

Diffstat:
Msrc/htvox.h | 6++++++
Msrc/htvox_scene.c | 72+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/src/htvox.h b/src/htvox.h @@ -17,6 +17,7 @@ #define HTVOX_H #include <rsys/rsys.h> +#include <float.h> /* Library symbol management */ #if defined(HTVOX_SHARED_BUILD) /* Build shared library */ @@ -41,6 +42,11 @@ struct htvox_voxel { size_t id; /* Indentifier of the voxel */ }; +#define HTVOX_VOXEL_NULL__ { DBL_MAX, SIZE_MAX } +static const struct htvox_voxel HTVOX_VOXEL_NULL = HTVOX_VOXEL_NULL__; + +#define HTVOX_VOXEL_NONE(Voxel) ((Voxel)->id == HTVOX_VOXEL_NULL.id) + struct htvox_hit { double distance; /* Distance from the ray origin to the impacted voxel */ struct htvox_voxel voxel; /* Intersected voxel */ diff --git a/src/htvox_scene.c b/src/htvox_scene.c @@ -561,7 +561,7 @@ res_T htvox_scene_for_each_voxel (struct htvox_scene* scn, void (*func) - (const double val, + (const double val, const size_t ivoxel, const double low[3], const double upp[3], @@ -640,3 +640,73 @@ htvox_scene_for_each_voxel return RES_OK; } +res_T +htvox_scene_at + (struct htvox_scene* scn, + const double position[3], + struct htvox_voxel* voxel) +{ + struct octree_index inode; + double scale_exp2; + double low[3]; + double pos[3]; + + if(!scn || !position || !voxel) return RES_BAD_ARG; + + *voxel = HTVOX_VOXEL_NULL; + + if(position[0] > scn->upper[0] || position[0] < scn->lower[0] + || position[1] > scn->upper[1] || position[1] < scn->lower[1] + || position[2] > scn->upper[2] || position[2] < scn->lower[2]) { + return RES_OK; + } + + /* Transform the position in the normalized octree space, + * i.e. octree lies in [0, 1]^2 */ + pos[0] = (position[0] - scn->oclow[0]) / (scn->ocupp[0] - scn->oclow[0]); + pos[1] = (position[1] - scn->oclow[1]) / (scn->ocupp[1] - scn->oclow[1]); + pos[2] = (position[2] - scn->oclow[2]) / (scn->ocupp[2] - scn->oclow[2]); + + /* Initialized the lower left corner of the current node */ + low[0] = 0; + low[1] = 0; + low[2] = 0; + + scale_exp2 = 0.5; + do { + struct octree_xnode* node = octree_buffer_get_node(&scn->buffer, inode); + + if(OCTREE_XNODE_IS_LEAF(node)) { /* Reach a leaf */ + const size_t page_nvoxs = scn->buffer.pagesize/sizeof(double); + struct octree_index ileaf; + + ileaf = octree_buffer_get_child_index(&scn->buffer, inode, 0); + voxel->data = *octree_buffer_get_leaf(&scn->buffer, ileaf); + voxel->id = ileaf.ipage * page_nvoxs + ileaf.inode; + + } else { + double mid[3]; + int ichild = 0; + + ASSERT(!OCTREE_XNODE_IS_EMPTY(node)); + + /* Compute the middle point of the node */ + mid[0] = low[0] + scale_exp2; + mid[1] = low[1] + scale_exp2; + mid[2] = low[2] + scale_exp2; + + /* Define the child of the current node into which pos `lies' and compute + * its lower left corner */ + if(pos[0] > mid[0]) { ichild |= 4; low[0] += mid[0]; } + if(pos[1] > mid[1]) { ichild |= 2; low[1] += mid[1]; } + if(pos[2] > mid[2]) { ichild |= 1; low[2] += mid[2]; } + + /* Fetch the child node */ + inode = octree_buffer_get_child_index(&scn->buffer, inode, ichild); + scale_exp2 *= 0.5; + } + } while(HTVOX_VOXEL_NONE(voxel)); + + return RES_OK; +} +