commit 7edac48da854da3190c5cd1e969b9cdb643bdb28
parent 7fa5a5eb80eb280cb6d33ebf5da6d7f0d9aec4f4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 13 Sep 2018 16:48:23 +0200
Ray-traced an image in test_svx_bintree_trace_ray
Diffstat:
4 files changed, 110 insertions(+), 56 deletions(-)
diff --git a/src/svx_bintree_trace_ray.c b/src/svx_bintree_trace_ray.c
@@ -179,7 +179,7 @@ svx_bintree_trace_ray
const double t_max = null_dir ? ray_range[1] : (upp - org) * ts;
const struct buffer_index iattr = buffer_get_child_attr_index
(&btree->buffer, inode, ichild_adjusted);
- ASSERT(t_min < t_max);
+ ASSERT(t_min <= t_max);
setup_hit(btree, iattr, t_min, t_max, low, scale_exp2, depth, is_leaf,
flip, &hit_tmp);
@@ -224,7 +224,7 @@ svx_bintree_trace_ray
}
/* Purse traversal */
- ASSERT(pos_min >= low && pos_min < low + scale_exp2);
+ ASSERT(pos_min >= low && pos_min <= low + scale_exp2);
low += scale_exp2; /* Lower bound of the next node to traverse */
pos_min = low; /* Snap the pos_min to the next node lower bound */
++ichild;
diff --git a/src/test_svx_bintree_trace_ray.c b/src/test_svx_bintree_trace_ray.c
@@ -16,18 +16,13 @@
#include "svx.h"
#include "test_svx_utils.h"
+#include <rsys/image.h>
#include <rsys/double2.h>
#include <rsys/double3.h>
#include <rsys/math.h>
#include <math.h>
-struct ray {
- double org[3];
- double dir[3];
- double range[2];
-};
-
struct scene {
enum svx_axis axis;
double origin;
@@ -160,6 +155,59 @@ hit_filter3
return 1;
}
+static void
+draw_image(FILE* stream, struct svx_tree* btree)
+{
+ struct camera cam;
+ unsigned char* pixels = NULL;
+ const size_t width = 512;
+ const size_t height = 512;
+ const double pos[3] = { 0, 0, 0};
+ const double tgt[3] = { 0, 0, 1};
+ const double up[3] = { 1, 0, 0};
+ struct image img;
+ double pix[2];
+ size_t ix, iy;
+
+ CHK(btree);
+ camera_init(&cam, pos, tgt, up, (double)width/(double)height);
+
+ image_init(NULL, &img);
+ CHK(image_setup(&img, width, height, sizeof_image_format(IMAGE_RGB8)*width,
+ IMAGE_RGB8, NULL) == RES_OK);
+ pixels = (unsigned char*)img.pixels;
+
+ FOR_EACH(iy, 0, height) {
+ pix[1] = (double)iy / (double)height;
+ FOR_EACH(ix, 0, width) {
+ struct svx_hit hit;
+ struct ray r;
+ size_t ipix = (iy*width + ix)*3/*#channels per pixel*/;
+ pix[0] = (double)ix / (double)width;
+ camera_ray(&cam, pix, &r);
+
+ CHK(svx_bintree_trace_ray
+ (btree, r.org, r.dir, r.range, NULL, hit_filter, &r, &hit) == RES_OK);
+ pixels[ipix+0] = 0;
+ pixels[ipix+1] = 0;
+ pixels[ipix+2] = 0;
+
+ if(!SVX_HIT_NONE(&hit)) {
+ double N[3] = {1, 0, 0};
+ const double dot = d3_dot(N, r.dir);
+ if(dot < 0) {
+ pixels[ipix+0] =(unsigned char)(255 * -dot);
+ } else {
+ pixels[ipix+2] =(unsigned char)(255 * dot);
+ }
+ }
+ }
+ }
+
+ CHK(image_write_ppm_stream(&img, 0, stream) == RES_OK);
+ image_release(&img);
+}
+
int
main(int argc, char** argv)
{
@@ -392,6 +440,8 @@ main(int argc, char** argv)
CHK(SVX_HIT_NONE(&hit));
CHK(accum == 1);
+ draw_image(stdout, btree);
+
CHK(svx_tree_ref_put(btree) == RES_OK);
CHK(svx_device_ref_put(dev) == RES_OK);
CHK(mem_allocated_size() == 0);
diff --git a/src/test_svx_octree_trace_ray.c b/src/test_svx_octree_trace_ray.c
@@ -26,17 +26,6 @@
#include <rsys/image.h>
#include <rsys/math.h>
-struct camera {
- double pos[3];
- double x[3], y[3], z[3]; /* Frame */
-};
-
-struct ray {
- double org[3];
- double dir[3];
- double range[3];
-};
-
struct scene {
double origin[3];
double vxsz[3];
@@ -44,43 +33,6 @@ struct scene {
double sphere_radius;
};
-static void
-camera_init
- (struct camera* cam,
- const double pos[3],
- const double tgt[3],
- const double up[3],
- const double proj_ratio)
-{
- const double fov_x = PI * 0.25;
- double d = 0.0;
- CHK(cam != NULL);
-
- d3_set(cam->pos, pos);
- d = d3_normalize(cam->z, d3_sub(cam->z, tgt, pos)); CHK(d != 0);
- d = d3_normalize(cam->x, d3_cross(cam->x, cam->z, up)); CHK(d != 0);
- d = d3_normalize(cam->y, d3_cross(cam->y, cam->z, cam->x)); CHK(d != 0);
- d3_divd(cam->z, cam->z, tan(fov_x*0.5));
- d3_divd(cam->y, cam->y, proj_ratio);
-}
-
-static void
-camera_ray
- (const struct camera* cam,
- const double pixel[2],
- struct ray* ray)
-{
- double x[3], y[3], f;
- CHK(cam && pixel && ray);
-
- d3_muld(x, cam->x, pixel[0]*2.0 - 1.0);
- d3_muld(y, cam->y, pixel[1]*2.0 - 1.0);
- d3_add(ray->dir, d3_add(ray->dir, x, y), cam->z);
- f = d3_normalize(ray->dir, ray->dir); CHK(f != 0);
- d3_set(ray->org, cam->pos);
- d2(ray->range, 0, INF);
-}
-
static char
sphere_intersect_aabb
(const double pos[3], /* Sphere position */
diff --git a/src/test_svx_utils.h b/src/test_svx_utils.h
@@ -16,7 +16,10 @@
#ifndef TEST_HTVOX_UTILS_H
#define TEST_HTVOX_UTILS_H
+#include <rsys/double2.h>
+#include <rsys/double3.h>
#include <rsys/mem_allocator.h>
+
#include <stdio.h>
enum data_type {
@@ -27,6 +30,55 @@ enum data_type {
TYPE_DOUBLE
};
+struct camera {
+ double pos[3];
+ double x[3], y[3], z[3]; /* Frame */
+};
+
+struct ray {
+ double org[3];
+ double dir[3];
+ double range[3];
+};
+
+static INLINE void
+camera_init
+ (struct camera* cam,
+ const double pos[3],
+ const double tgt[3],
+ const double up[3],
+ const double proj_ratio)
+{
+ const double fov_x = PI * 0.25;
+ double d = 0.0;
+ CHK(cam != NULL);
+
+ d3_set(cam->pos, pos);
+ d = d3_normalize(cam->z, d3_sub(cam->z, tgt, pos)); CHK(d != 0);
+ d = d3_normalize(cam->x, d3_cross(cam->x, cam->z, up)); CHK(d != 0);
+ d = d3_normalize(cam->y, d3_cross(cam->y, cam->z, cam->x)); CHK(d != 0);
+ d3_divd(cam->z, cam->z, tan(fov_x*0.5));
+ d3_divd(cam->y, cam->y, proj_ratio);
+}
+
+static INLINE void
+camera_ray
+ (const struct camera* cam,
+ const double pixel[2],
+ struct ray* ray)
+{
+ double x[3], y[3], f;
+ CHK(cam && pixel && ray);
+
+ d3_muld(x, cam->x, pixel[0]*2.0 - 1.0);
+ d3_muld(y, cam->y, pixel[1]*2.0 - 1.0);
+ d3_add(ray->dir, d3_add(ray->dir, x, y), cam->z);
+ f = d3_normalize(ray->dir, ray->dir); CHK(f != 0);
+ d3_set(ray->org, cam->pos);
+ d2(ray->range, 0, INF);
+}
+
+
static INLINE const char*
data_type_to_string(const enum data_type type)
{