star-vx

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

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:
Msrc/svx_bintree_trace_ray.c | 4++--
Msrc/test_svx_bintree_trace_ray.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/test_svx_octree_trace_ray.c | 48------------------------------------------------
Msrc/test_svx_utils.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
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) {