star-vx

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

test_svx_utils.h (6210B)


      1 /* Copyright (C) 2018, 2020-2025 |Méso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2018 Université Paul Sabatier
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #ifndef TEST_SVX_UTILS_H
     18 #define TEST_SVX_UTILS_H
     19 
     20 #include <rsys/double2.h>
     21 #include <rsys/double3.h>
     22 #include <rsys/image.h>
     23 #include <rsys/mem_allocator.h>
     24 
     25 #include <stdio.h>
     26 
     27 enum data_type {
     28   TYPE_CHAR,
     29   TYPE_INT,
     30   TYPE_LONG,
     31   TYPE_FLOAT,
     32   TYPE_DOUBLE
     33 };
     34 
     35 struct camera {
     36   double pos[3];
     37   double x[3], y[3], z[3]; /* Frame */
     38 };
     39 
     40 struct ray {
     41   double org[3];
     42   double dir[3];
     43   double range[3];
     44 };
     45 
     46 static INLINE void
     47 camera_init
     48   (struct camera* cam,
     49    const double pos[3],
     50    const double tgt[3],
     51    const double up[3],
     52    const double proj_ratio)
     53 {
     54   const double fov_x = PI * 0.25;
     55   double d = 0.0;
     56   CHK(cam != NULL);
     57 
     58   d3_set(cam->pos, pos);
     59   d = d3_normalize(cam->z, d3_sub(cam->z, tgt, pos)); CHK(d != 0);
     60   d = d3_normalize(cam->x, d3_cross(cam->x, cam->z, up)); CHK(d != 0);
     61   d = d3_normalize(cam->y, d3_cross(cam->y, cam->z, cam->x)); CHK(d != 0);
     62   d3_divd(cam->z, cam->z, tan(fov_x*0.5));
     63   d3_divd(cam->y, cam->y, proj_ratio);
     64 }
     65 
     66 static INLINE void
     67 camera_ray
     68   (const struct camera* cam,
     69    const double pixel[2],
     70    struct ray* ray)
     71 {
     72   double x[3], y[3], f;
     73   CHK(cam && pixel && ray);
     74 
     75   d3_muld(x, cam->x, pixel[0]*2.0 - 1.0);
     76   d3_muld(y, cam->y, pixel[1]*2.0 - 1.0);
     77   d3_add(ray->dir, d3_add(ray->dir, x, y), cam->z);
     78   f = d3_normalize(ray->dir, ray->dir); CHK(f != 0);
     79   d3_set(ray->org, cam->pos);
     80   d2(ray->range, 0, INF);
     81 }
     82 
     83 
     84 static INLINE const char*
     85 data_type_to_string(const enum data_type type)
     86 {
     87   switch(type) {
     88     case TYPE_CHAR: return "char";
     89     case TYPE_INT: return "int";
     90     case TYPE_LONG: return "long";
     91     case TYPE_FLOAT: return "float";
     92     case TYPE_DOUBLE: return "double";
     93     default: FATAL("Unreachable code.\n");
     94   }
     95 }
     96 
     97 static INLINE void
     98 write_leaf_vertices
     99   (const struct svx_voxel* leaf,
    100    const size_t ileaf,
    101    void* context)
    102 {
    103   FILE* stream = context;
    104   (void)ileaf;
    105   CHK(stream != NULL);
    106   CHK(leaf != NULL);
    107   fprintf(stream,
    108     "%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n"
    109     "%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n",
    110     leaf->lower[0], leaf->lower[1], leaf->lower[2],
    111     leaf->upper[0], leaf->lower[1], leaf->lower[2],
    112     leaf->lower[0], leaf->upper[1], leaf->lower[2],
    113     leaf->upper[0], leaf->upper[1], leaf->lower[2],
    114     leaf->lower[0], leaf->lower[1], leaf->upper[2],
    115     leaf->upper[0], leaf->lower[1], leaf->upper[2],
    116     leaf->lower[0], leaf->upper[1], leaf->upper[2],
    117     leaf->upper[0], leaf->upper[1], leaf->upper[2]);
    118 }
    119 
    120 static INLINE void
    121 write_leaf_cells
    122   (const struct svx_voxel* leaf,
    123    const size_t ileaf,
    124    void* context)
    125 {
    126   FILE* stream = context;
    127   CHK(stream != NULL);
    128   CHK(leaf != NULL);
    129   fprintf(stream, "8 %lu %lu %lu %lu %lu %lu %lu %lu\n",
    130     (unsigned long)(ileaf*8 + 0),
    131     (unsigned long)(ileaf*8 + 1),
    132     (unsigned long)(ileaf*8 + 2),
    133     (unsigned long)(ileaf*8 + 3),
    134     (unsigned long)(ileaf*8 + 4),
    135     (unsigned long)(ileaf*8 + 5),
    136     (unsigned long)(ileaf*8 + 6),
    137     (unsigned long)(ileaf*8 + 7));
    138 }
    139 
    140 static INLINE void
    141 dump_data
    142   (FILE* stream,
    143    struct svx_tree* tree,
    144    const enum data_type type,
    145    const size_t numcomps,
    146    void (*write_leaf_data)
    147     (const struct svx_voxel* leaf, const size_t ileaf, void* ctx))
    148 {
    149   struct svx_tree_desc desc;
    150   size_t ileaf;
    151 
    152   CHK(stream != NULL);
    153   CHK(tree != NULL);
    154   CHK(write_leaf_data);
    155 
    156   fprintf(stream, "# vtk DataFile Version 2.0\n");
    157   fprintf(stream, "Volume\n");
    158   fprintf(stream, "ASCII\n");
    159   fprintf(stream, "DATASET UNSTRUCTURED_GRID\n");
    160 
    161   CHK(svx_tree_get_desc(tree, &desc) == RES_OK);
    162   CHK(desc.type == SVX_OCTREE); /* FIXME currently only octree are supported */
    163   fprintf(stream, "POINTS %lu float\n", (unsigned long)(desc.nleaves* 8));
    164   CHK(svx_tree_for_each_leaf(tree, write_leaf_vertices, stream) == RES_OK);
    165 
    166   fprintf(stream, "CELLS %lu %lu\n",
    167     (unsigned long)desc.nleaves,
    168     (unsigned long)(desc.nleaves*(8/*#verts per leaf*/ + 1/*1st field of a cell*/)));
    169   CHK(svx_tree_for_each_leaf(tree, write_leaf_cells, stream) == RES_OK);
    170 
    171   fprintf(stream, "CELL_TYPES %lu\n", (unsigned long)desc.nleaves);
    172   FOR_EACH(ileaf, 0, desc.nleaves) fprintf(stream, "11\n");
    173 
    174   fprintf(stream, "CELL_DATA %lu\n", (unsigned long)desc.nleaves);
    175   fprintf(stream, "SCALARS K %s %lu\n",
    176     data_type_to_string(type), (unsigned long)numcomps);
    177   fprintf(stream, "LOOKUP_TABLE default\n");
    178   CHK(svx_tree_for_each_leaf(tree, write_leaf_data, stream) == RES_OK);
    179 }
    180 
    181 static INLINE void
    182 check_img_eq(const struct image* img0, const struct image* img1)
    183 {
    184   size_t ix, iy;
    185   size_t pixsz;
    186 
    187   CHK(img0 && img1);
    188   CHK(img0->format == IMAGE_RGB8);
    189   CHK(img1->format == IMAGE_RGB8);
    190   CHK(img0->width == img1->width);
    191   CHK(img0->height == img1->height);
    192   CHK(img0->pitch == img1->pitch);
    193 
    194   pixsz = sizeof_image_format(img0->format);
    195 
    196   FOR_EACH(iy, 0, img0->height) {
    197     const char* row0 = img0->pixels + iy * img0->pitch;
    198     const char* row1 = img1->pixels + iy * img1->pitch;
    199     FOR_EACH(ix, 0, img0->width) {
    200       const uint8_t* pix0 = (const uint8_t*)(row0 + ix*pixsz);
    201       const uint8_t* pix1 = (const uint8_t*)(row1 + ix*pixsz);
    202       CHK(pix0[0] == pix1[0]);
    203       CHK(pix0[1] == pix1[1]);
    204       CHK(pix0[2] == pix1[2]);
    205     }
    206   }
    207 }
    208 
    209 static INLINE void
    210 check_memory_allocator(struct mem_allocator* allocator)
    211 {
    212   if(MEM_ALLOCATED_SIZE(allocator)) {
    213     char dump[512];
    214     MEM_DUMP(allocator, dump, sizeof(dump)/sizeof(char));
    215     fprintf(stderr, "%s\n", dump);
    216     FATAL("Memory leaks\n");
    217   }
    218 }
    219 
    220 #endif /* TEST_SVX_UTILS_H */
    221