commit eae934e11339dc57596ea4f902d6dde1275461d2
parent b1d8a75d98c5eabf1fda261e8f66c64fb8c934cf
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 4 Apr 2018 11:53:26 +0200
Begin the implementation of a trace_ray test
Diffstat:
2 files changed, 153 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -88,6 +88,7 @@ if(NOT NO_TEST)
new_test(test_svx_device)
new_test(test_svx_octree)
+ new_test(test_svx_octree_trace_ray)
endif()
################################################################################
diff --git a/src/test_svx_octree_trace_ray.c b/src/test_svx_octree_trace_ray.c
@@ -0,0 +1,152 @@
+/* Copyright (C) 2018 Université Paul Sabatier, |Meso|Star>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "svx.h"
+#include "test_svx_utils.h"
+
+#include <rsys/math.h>
+
+struct scene {
+ double origin[3];
+ double vxsz[3];
+ double sphere_pos[3];
+ double sphere_radius;
+};
+
+static char
+sphere_intersect_aabb
+ (const double pos[3], /* Sphere position */
+ const double radius, /* Sphere radius */
+ const double low[3], /* AABB lower bound */
+ const double upp[3]) /* AABB upper bound */
+{
+ double v[3];
+ double sqr_dst;
+
+ CHK(pos != NULL);
+ CHK(low != NULL);
+ CHK(upp != NULL);
+ CHK(radius > 0);
+
+ v[0] = pos[0]<low[0] ? low[0]-pos[0] : (pos[0]>upp[0] ? pos[0]-upp[0] : 0);
+ v[1] = pos[1]<low[1] ? low[1]-pos[1] : (pos[1]>upp[1] ? pos[1]-upp[1] : 0);
+ v[2] = pos[2]<low[2] ? low[2]-pos[2] : (pos[2]>upp[2] ? pos[2]-upp[2] : 0);
+
+ sqr_dst = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+
+ return sqr_dst <= radius*radius;
+}
+
+static void
+voxel_get(const size_t xyz[3], void* dst, void* ctx)
+{
+ const struct scene* scn = ctx;
+ char* val = dst;
+ double low[3];
+ double upp[3];
+ CHK(xyz != NULL);
+ CHK(dst != NULL);
+ CHK(ctx != NULL);
+
+ /* Compute the AABB of the voxel */
+ low[0] = (double)xyz[0] * scn->vxsz[0] + scn->origin[0];
+ low[1] = (double)xyz[1] * scn->vxsz[1] + scn->origin[1];
+ low[2] = (double)xyz[2] * scn->vxsz[2] + scn->origin[2];
+ upp[0] = low[0] + scn->vxsz[0];
+ upp[1] = low[1] + scn->vxsz[1];
+ upp[2] = low[2] + scn->vxsz[2];
+
+ /* Binary octree, i.e. it stores if the voxel intersect the sphere or not */
+ *val = sphere_intersect_aabb(scn->sphere_pos, scn->sphere_radius, low, upp);
+}
+
+static void
+voxels_merge(void* dst, const void* voxels[], const size_t nvoxels, void* ctx)
+{
+ size_t ivoxel;
+ char tmp = 0;
+ char* val = dst;
+
+ CHK(dst && voxels && nvoxels && ctx);
+
+ for(ivoxel=0; tmp && ivoxel<nvoxels; ++ivoxel) {
+ const char* voxel_data = voxels[ivoxel];
+ tmp = *voxel_data;
+ }
+ *val = tmp;
+}
+
+static int
+voxels_challenge_merge(const void* voxels[], const size_t nvoxels, void* ctx)
+{
+ size_t ivoxel;
+ int merge = 1;
+ char ref;
+
+ CHK(voxels && nvoxels && ctx);
+
+ ref = *(char*)(voxels[0]);
+
+ for(ivoxel=1; merge && ivoxel<nvoxels; ++ivoxel) {
+ const char* voxel_data = voxels[ivoxel];
+ merge = (ref == *voxel_data);
+ }
+ return merge;
+}
+
+int
+main(int argc, char** argv)
+{
+ struct scene scn;
+ struct svx_device* dev = NULL;
+ struct svx_octree* oct = NULL;
+ struct svx_voxel_desc voxel_desc = SVX_VOXEL_DESC_NULL;
+ const double lower[3] = {-1,-1,-1};
+ const double upper[3] = { 1, 1, 1};
+ const size_t def[3] = {32, 32, 32};
+ double scnsz[3];
+ (void)argc, (void)argv;
+
+ CHK(svx_device_create(NULL, NULL, 1, &dev) == RES_OK);
+
+ scnsz[0] = upper[0] - lower[0];
+ scnsz[1] = upper[1] - lower[1];
+ scnsz[2] = upper[2] - lower[2];
+
+ scn.origin[0] = lower[0];
+ scn.origin[1] = lower[1];
+ scn.origin[2] = lower[2];
+ scn.vxsz[0] = scnsz[0] / (double)def[0];
+ scn.vxsz[1] = scnsz[1] / (double)def[1];
+ scn.vxsz[2] = scnsz[2] / (double)def[2];
+ scn.sphere_pos[0] = lower[0] + scnsz[0] * 0.5;
+ scn.sphere_pos[1] = lower[1] + scnsz[1] * 0.5;
+ scn.sphere_pos[2] = lower[2] + scnsz[2] * 0.5;
+ scn.sphere_radius = MMIN(MMIN(scnsz[0], scnsz[1]), scnsz[2]) * 0.25;
+
+ voxel_desc.get = voxel_get;
+ voxel_desc.merge = voxels_merge;
+ voxel_desc.challenge_merge = voxels_challenge_merge;
+ voxel_desc.context = &scn;
+ voxel_desc.size = sizeof(char);
+
+ CHK(svx_octree_create(dev, lower, upper, def, &voxel_desc, &oct) == RES_OK);
+
+ CHK(svx_octree_ref_put(oct) == RES_OK);
+ CHK(svx_device_ref_put(dev) == RES_OK);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
+