star-2d

Contour structuring for efficient 2D geometric queries
git clone git://git.meso-star.fr/star-2d.git
Log | Files | Refs | README | LICENSE

test_s2d_trace_ray.c (8684B)


      1 /* Copyright (C) 2016-2021, 2023 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "s2d.h"
     17 #include "test_s2d_utils.h"
     18 
     19 #include <rsys/float2.h>
     20 
     21 struct ray_data {
     22   struct s2d_primitive prim;
     23   float ray_org[2];
     24   float ray_dir[2];
     25   float ray_range[2];
     26 };
     27 
     28 static int
     29 filter_hit
     30   (const struct s2d_hit* hit,
     31    const float org[2],
     32    const float dir[2],
     33    const float range[2],
     34    void* ray_data,
     35    void* filter_data)
     36 {
     37   struct ray_data* data = ray_data;
     38   CHK(hit != NULL);
     39   CHK(org != NULL);
     40   CHK(dir != NULL);
     41   CHK(range != NULL);
     42   CHK((intptr_t)filter_data == 0xDEADBEEF);
     43   if(!ray_data) return 0;
     44   CHK(f2_eq(data->ray_org, org));
     45   CHK(f2_eq(data->ray_dir, dir));
     46   CHK(f2_eq(data->ray_range, range));
     47   return S2D_PRIMITIVE_EQ(&data->prim, &hit->prim);
     48 }
     49 
     50 int
     51 main(int argc, char** argv)
     52 {
     53   struct ray_data ray_data;
     54   struct s2d_device* dev;
     55   struct s2d_shape* shape;
     56   struct s2d_scene* scn;
     57   struct s2d_scene_view* scnview;
     58   struct s2d_vertex_data vdata;
     59   struct s2d_hit hit;
     60   struct s2d_primitive prim, prim2;
     61   struct mem_allocator allocator;
     62   float org[2], dir[3], range[2];
     63   float N[3] = {0.f, 0.f, 0.f};
     64   (void)argc, (void)argv;
     65 
     66   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     67 
     68   CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
     69   CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK);
     70   CHK(s2d_scene_create(dev, &scn) == RES_OK);
     71 
     72   vdata.type = S2D_FLOAT2;
     73   vdata.usage = S2D_POSITION;
     74   vdata.get = line_segments_get_position;
     75   CHK(s2d_line_segments_setup_indexed_vertices
     76     (shape, square_nsegs, line_segments_get_ids, square_nverts, &vdata, 1,
     77      (void*)&square_desc) == RES_OK);
     78 
     79   #define SET_FILTER_FUNC s2d_line_segments_set_hit_filter_function
     80   CHK(SET_FILTER_FUNC(NULL, NULL, NULL) == RES_BAD_ARG);
     81   CHK(SET_FILTER_FUNC(shape, NULL, NULL) == RES_OK);
     82   CHK(SET_FILTER_FUNC(NULL, filter_hit, NULL) == RES_BAD_ARG);
     83   CHK(SET_FILTER_FUNC(shape, filter_hit, NULL) == RES_OK);
     84   CHK(SET_FILTER_FUNC(shape, filter_hit, (void*)0xDEADBEEF) == RES_OK);
     85   #undef SET_FILTER_FUNC
     86 
     87   CHK(s2d_scene_attach_shape(scn, shape) == RES_OK);
     88 
     89   f2(org, 10.f, 10.f);
     90   f2(dir, 0.f, -1.f);
     91   f2(range, 0, FLT_MAX);
     92 
     93   CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK);
     94 
     95   #define RT s2d_scene_view_trace_ray
     96   CHK(RT(NULL, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
     97   CHK(RT(scnview, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
     98   CHK(RT(NULL, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
     99   CHK(RT(scnview, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG);
    100   CHK(RT(NULL, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG);
    101   CHK(RT(scnview, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG);
    102   CHK(RT(NULL, org, dir, NULL, NULL, NULL) == RES_BAD_ARG);
    103   CHK(RT(scnview, org, dir, NULL, NULL, NULL) == RES_BAD_ARG);
    104   CHK(RT(NULL, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG);
    105   CHK(RT(scnview, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG);
    106   CHK(RT(NULL, org, NULL, range, NULL, NULL) == RES_BAD_ARG);
    107   CHK(RT(scnview, org, NULL, range, NULL, NULL) == RES_BAD_ARG);
    108   CHK(RT(NULL, NULL, dir, range, NULL, NULL) == RES_BAD_ARG);
    109   CHK(RT(scnview, NULL, dir, range, NULL, NULL) == RES_BAD_ARG);
    110   CHK(RT(NULL, org, dir, range, NULL, NULL) == RES_BAD_ARG);
    111   CHK(RT(scnview, org, dir, range, NULL, NULL) == RES_BAD_ARG);
    112   CHK(RT(NULL, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
    113   CHK(RT(scnview, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
    114   CHK(RT(NULL, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
    115   CHK(RT(scnview, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG);
    116   CHK(RT(NULL, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG);
    117   CHK(RT(scnview, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG);
    118   CHK(RT(NULL, org, dir, NULL, NULL, &hit) == RES_BAD_ARG);
    119   CHK(RT(scnview, org, dir, NULL, NULL, &hit) == RES_BAD_ARG);
    120   CHK(RT(NULL, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG);
    121   CHK(RT(scnview, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG);
    122   CHK(RT(NULL, org, NULL, range, NULL, &hit) == RES_BAD_ARG);
    123   CHK(RT(scnview, org, NULL, range, NULL, &hit) == RES_BAD_ARG);
    124   CHK(RT(NULL, NULL, dir, range, NULL, &hit) == RES_BAD_ARG);
    125   CHK(RT(scnview, NULL, dir, range, NULL, &hit) == RES_BAD_ARG);
    126   CHK(RT(NULL, org, dir, range, NULL, &hit) == RES_BAD_ARG);
    127 
    128   f2(dir, 0.f, -1.f);
    129   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    130   CHK(S2D_HIT_NONE(&hit) == 0);
    131   CHK(hit.prim.prim_id == 0);
    132   f2_normalize(N, hit.normal);
    133   CHK(f2_eq_eps(N, f2(dir, 0.f, 1.f), 1.e-6f) == 1);
    134   CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
    135   CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
    136 
    137   prim = hit.prim;
    138 
    139   f2(dir, 0.f, -1.f);
    140   range[1] = 0.5f;
    141   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    142   CHK(S2D_HIT_NONE(&hit) == 1);
    143   range[1] = FLT_MAX;
    144 
    145 
    146   f2(dir, 0.f, -1.f);
    147   f2_set(ray_data.ray_org, org);
    148   f2_set(ray_data.ray_dir, dir);
    149   f2_set(ray_data.ray_range, range);
    150   ray_data.prim = prim;
    151   CHK(RT(scnview, org, dir, range, &ray_data, &hit) == RES_OK);
    152   CHK(S2D_HIT_NONE(&hit) == 1);
    153 
    154   f2(dir, -1.f, 0.f);
    155   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    156   CHK(S2D_HIT_NONE(&hit) == 0);
    157   CHK(hit.prim.prim_id == 1);
    158   f2_normalize(N, hit.normal);
    159   CHK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f) == 1);
    160   CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
    161   CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
    162 
    163   f2(dir, 0.f, 1.f);
    164   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    165   CHK(S2D_HIT_NONE(&hit) == 0);
    166   CHK(hit.prim.prim_id == 2);
    167   f2_normalize(N, hit.normal);
    168   CHK(f2_eq_eps(N, f2(dir, 0.f, -1.f), 1.e-6f) == 1);
    169   CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
    170   CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
    171 
    172   prim2 = hit.prim;
    173 
    174   f2(org, 10.f, 12.f);
    175   f2(dir, 0.f, -1.f);
    176   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    177   CHK(S2D_HIT_NONE(&hit) == 0);
    178   CHK(S2D_PRIMITIVE_EQ(&hit.prim, &prim2) == 1);
    179 
    180   f2_set(ray_data.ray_org, org);
    181   f2_set(ray_data.ray_dir, dir);
    182   f2_set(ray_data.ray_range, range);
    183   ray_data.prim = prim2;
    184   CHK(RT(scnview, org, dir, range, &ray_data, &hit) == RES_OK);
    185   CHK(S2D_HIT_NONE(&hit) == 0);
    186   CHK(S2D_PRIMITIVE_EQ(&hit.prim, &prim) == 1);
    187 
    188   f2_splat(org, 10.f);
    189   f2(dir, 1.f, 0.f);
    190   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    191   CHK(S2D_HIT_NONE(&hit) == 0);
    192   CHK(hit.prim.prim_id == 3);
    193   f2_normalize(N, hit.normal);
    194   CHK(f2_eq_eps(N, f2(dir, -1.f, 0.f), 1.e-6f) == 1);
    195   CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
    196   CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1);
    197 
    198   f2(range, 1.f, -1.f);
    199   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    200   CHK(S2D_HIT_NONE(&hit) == 1);
    201 
    202   f2(dir, 1.f, 1.f);
    203   f2(range, 0.f, FLT_MAX);
    204   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_BAD_ARG);
    205 
    206   CHK(s2d_scene_view_ref_put(scnview) == RES_OK);
    207 
    208   CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK);
    209   f2(dir, 0.75f, -1.f);
    210   f2_normalize(dir, dir);
    211   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    212   CHK(S2D_HIT_NONE(&hit) == 0);
    213   CHK(eq_epsf(hit.u, 0.125f, 1.e-6f) == 1);
    214   CHK(eq_epsf(hit.distance, 1.25, 1.E-6f) == 1);
    215 
    216   f2(dir, -1.f, 0.25f);
    217   f2_normalize(dir, dir);
    218   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    219   CHK(S2D_HIT_NONE(&hit) == 0);
    220   CHK(eq_epsf(hit.u, 0.625, 1.e-6f) == 1);
    221   CHK(eq_epsf(hit.distance, (float)sqrt(1.0625f), 1e-6f) == 1);
    222 
    223   f2(org, 8.75f, 10.f);
    224   f2(dir, -1, 0.f);
    225   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    226   CHK(S2D_HIT_NONE(&hit) == 1);
    227 
    228   f2(dir, 1, 0.f);
    229   CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK);
    230   CHK(S2D_HIT_NONE(&hit) == 0);
    231   CHK(hit.prim.prim_id == 1);
    232   f2_normalize(N, hit.normal);
    233   CHK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f) == 1);
    234   CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1);
    235   CHK(eq_epsf(hit.distance, 0.25f, 1.e-6f) == 1);
    236 
    237   CHK(s2d_scene_view_ref_put(scnview) == RES_OK);
    238 
    239   CHK(s2d_device_ref_put(dev) == RES_OK);
    240   CHK(s2d_shape_ref_put(shape) == RES_OK);
    241   CHK(s2d_scene_ref_put(scn) == RES_OK);
    242 
    243   check_memory_allocator(&allocator);
    244   mem_shutdown_proxy_allocator(&allocator);
    245   CHK(mem_allocated_size() == 0);
    246 
    247   return 0;
    248 }
    249