star-vx

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

commit 3467e2d3dda84ea28cd0d10ac16c1759d7c09fb3
parent d01a4ad76131dd4e236fb569823dae267dcd27cc
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  6 Apr 2018 10:01:48 +0200

Push further the trace_ray test

Use the svx_octree_trace_ray function to draw an image of a volumic
scene.

Diffstat:
Msrc/test_svx_octree_trace_ray.c | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 104 insertions(+), 2 deletions(-)

diff --git a/src/test_svx_octree_trace_ray.c b/src/test_svx_octree_trace_ray.c @@ -22,8 +22,14 @@ #include <rsys/double2.h> #include <rsys/double3.h> +#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]; @@ -37,6 +43,43 @@ 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 */ @@ -118,7 +161,7 @@ voxels_challenge_merge(const void* voxels[], const size_t nvoxels, void* ctx) return merge; } -static void +static INLINE void write_scalars (const struct svx_voxel* leaf, const size_t ileaf, @@ -190,6 +233,63 @@ hit_challenge(const struct svx_hit* hit, void* context) return 1; } +static void +draw_image(FILE* stream, struct svx_octree* oct, const struct scene* scn) +{ + struct camera cam; + unsigned char* pixels = NULL; + const size_t width = 512; + const size_t height = 512; + const double pos[3] = { 0,-2, 0}; + const double tgt[3] = { 0, 0, 0}; + const double up[3] = { 0, 0, 1}; + struct image img; + double pix[2]; + size_t ix, iy; + + CHK(oct); + 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_octree_trace_ray + (oct, r.org, r.dir, r.range, NULL, hit_filter, &r, &hit) == RES_OK); + if(SVX_HIT_NONE(&hit)) { + pixels[ipix+0] = 0; + pixels[ipix+1] = 0; + pixels[ipix+2] = 0; + } else { + double N[3]; + N[0] = (r.org[0] + hit.distance * r.dir[0]) - scn->sphere_pos[0]; + N[1] = (r.org[1] + hit.distance * r.dir[1]) - scn->sphere_pos[1]; + N[2] = (r.org[2] + hit.distance * r.dir[2]) - scn->sphere_pos[2]; + CHK(d3_normalize(N, N) != 0); + N[0] = fabs(N[0]); + N[1] = fabs(N[1]); + N[2] = fabs(N[2]); + pixels[ipix+0] = (unsigned char)(N[0] * 255.0); + pixels[ipix+1] = (unsigned char)(N[1] * 255.0); + pixels[ipix+2] = (unsigned char)(N[2] * 255.0); + } + } + } + + CHK(image_write_ppm_stream(&img, 0, stream) == RES_OK); + image_release(&img); +} + int main(int argc, char** argv) { @@ -235,7 +335,7 @@ main(int argc, char** argv) CHK(svx_octree_create(dev, lower, upper, def, &voxel_desc, &oct) == RES_OK); - dump_data(stdout, oct, CHAR, 1, write_scalars); + /*dump_data(stdout, oct, CHAR, 1, write_scalars);*/ #define RT svx_octree_trace_ray d3(r.org, -5,-5, 0); @@ -314,6 +414,8 @@ main(int argc, char** argv) CHK(SVX_HIT_NONE(&hit)); CHK(accum != 0); + draw_image(stdout, oct, &scn); + CHK(svx_octree_ref_put(oct) == RES_OK); CHK(svx_device_ref_put(dev) == RES_OK); CHK(mem_allocated_size() == 0);