star-3d

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

test_s3d_scene.c (13204B)


      1 /* Copyright (C) 2015-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 "s3d.h"
     17 #include "test_s3d_utils.h"
     18 #include "test_s3d_cbox.h"
     19 
     20 #include <rsys/math.h>
     21 
     22 static const float cube_verts[] = {
     23   5.f, 5.f, 5.f,
     24   6.f, 5.f, 5.f,
     25   5.f, 6.f, 5.f,
     26   6.f, 6.f, 5.f,
     27   5.f, 5.f, 6.f,
     28   6.f, 5.f, 6.f,
     29   5.f, 6.f, 6.f,
     30   6.f, 6.f, 6.f
     31 };
     32 static const unsigned cube_nverts = sizeof(cube_verts) / (sizeof(float)*3);
     33 
     34 /* Front faces are CW. The normals point into the cube */
     35 static const unsigned cube_ids[] = {
     36   0, 2, 1, 1, 2, 3, /* Front */
     37   0, 4, 2, 2, 4, 6, /* Left */
     38   4, 5, 6, 6, 5, 7, /* Back */
     39   3, 7, 1, 1, 7, 5, /* Right */
     40   2, 6, 3, 3, 6, 7, /* Top */
     41   0, 1, 4, 4, 1, 5 /* Bottom */
     42 };
     43 static const unsigned cube_ntris = sizeof(cube_ids) / (sizeof(unsigned)*3);
     44 
     45 static void
     46 cube_get_ids(const unsigned itri, unsigned ids[3], void* data)
     47 {
     48   const unsigned id = itri * 3;
     49   CHK(data == NULL);
     50   CHK(ids != NULL);
     51   CHK(itri < cube_ntris);
     52   ids[0] = cube_ids[id + 0];
     53   ids[1] = cube_ids[id + 1];
     54   ids[2] = cube_ids[id + 2];
     55 }
     56 
     57 static void
     58 cube_get_pos(const unsigned ivert, float pos[3], void* data)
     59 {
     60   const unsigned i = ivert*3;
     61   CHK(data == NULL);
     62   CHK(pos != NULL);
     63   CHK(ivert < cube_nverts);
     64   pos[0] = cube_verts[i + 0];
     65   pos[1] = cube_verts[i + 1];
     66   pos[2] = cube_verts[i + 2];
     67 }
     68 
     69 int
     70 main(int argc, char** argv)
     71 {
     72   struct mem_allocator allocator;
     73   struct s3d_primitive prims[10];
     74   struct s3d_device* dev, *dev2;
     75   struct s3d_scene* scn;
     76   struct s3d_scene* scn2;
     77   struct s3d_scene* scn3;
     78   struct s3d_scene_view* scnview;
     79   struct s3d_scene_view* scnview2;
     80   struct s3d_scene_view* scnview3;
     81   struct s3d_vertex_data attribs;
     82   struct s3d_shape* shapes[4];
     83   const size_t nshapes = sizeof(shapes)/sizeof(struct s3d_shape*);
     84   void* data = (void*)&cbox_walls_desc;
     85   size_t i, n;
     86   size_t nprims;
     87   float area, volume, lower[3], upper[3];
     88   unsigned id;
     89   int mask;
     90   (void)argc, (void)argv;
     91 
     92   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     93 
     94   CHK(s3d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
     95   FOR_EACH(i, 0, nshapes)
     96     CHK(s3d_shape_create_mesh(dev, shapes + i) == RES_OK);
     97 
     98   CHK(s3d_scene_create(NULL, NULL) == RES_BAD_ARG);
     99   CHK(s3d_scene_create(dev, NULL) == RES_BAD_ARG);
    100   CHK(s3d_scene_create(NULL, &scn) == RES_BAD_ARG);
    101   CHK(s3d_scene_create(dev, &scn) == RES_OK);
    102   CHK(s3d_scene_create(dev, &scn2) == RES_OK);
    103   CHK(s3d_scene_create(dev, &scn3) == RES_OK);
    104 
    105   CHK(s3d_scene_get_shapes_count(NULL, NULL) == RES_BAD_ARG);
    106   CHK(s3d_scene_get_shapes_count(scn, NULL) == RES_BAD_ARG);
    107   CHK(s3d_scene_get_shapes_count(NULL, &n) == RES_BAD_ARG);
    108   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    109   CHK(n == 0);
    110 
    111   CHK(s3d_scene_attach_shape(NULL, NULL) == RES_BAD_ARG);
    112   CHK(s3d_scene_attach_shape(scn, NULL) == RES_BAD_ARG);
    113   CHK(s3d_scene_attach_shape(NULL, shapes[0]) == RES_BAD_ARG);
    114   CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK);
    115   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    116   CHK(n == 1);
    117   CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK);
    118   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    119   CHK(n == 1);
    120 
    121   CHK(s3d_scene_detach_shape(NULL, NULL) == RES_BAD_ARG);
    122   CHK(s3d_scene_detach_shape(scn, NULL) == RES_BAD_ARG);
    123   CHK(s3d_scene_detach_shape(NULL, shapes[0]) == RES_BAD_ARG);
    124   CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK);
    125   CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_BAD_ARG);
    126   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    127   CHK(n == 0);
    128 
    129   FOR_EACH(i, 1, nshapes) {
    130     CHK(s3d_scene_attach_shape(scn, shapes[i]) == RES_OK);
    131     CHK(s3d_shape_ref_put(shapes[i]) == RES_OK);
    132   }
    133   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    134   CHK(n == nshapes - 1);
    135 
    136   CHK(s3d_scene_instantiate(NULL, NULL) == RES_BAD_ARG);
    137   CHK(s3d_scene_instantiate(scn, NULL) == RES_BAD_ARG);
    138   CHK(s3d_scene_instantiate(NULL, shapes + 1) == RES_BAD_ARG);
    139   CHK(s3d_scene_instantiate(scn, shapes + 1) == RES_OK);
    140 
    141   CHK(s3d_shape_get_id(NULL, NULL) == RES_BAD_ARG);
    142   CHK(s3d_shape_get_id(shapes[1], NULL) == RES_BAD_ARG);
    143   CHK(s3d_shape_get_id(NULL, &id) == RES_BAD_ARG);
    144   CHK(s3d_shape_get_id(shapes[1], &id) == RES_OK);
    145   CHK(id != S3D_INVALID_ID);
    146 
    147   CHK(s3d_scene_clear(NULL) == RES_BAD_ARG);
    148   CHK(s3d_scene_clear(scn) == RES_OK);
    149   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    150   CHK(n == 0);
    151   CHK(s3d_scene_clear(scn) == RES_OK);
    152   CHK(s3d_scene_instantiate(scn, shapes + 2) == RES_OK);
    153   CHK(s3d_scene_attach_shape(scn, shapes[2]) == RES_BAD_ARG);
    154 
    155   CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK);
    156   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    157   CHK(n == 1);
    158 
    159   CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK);
    160   CHK(s3d_scene_view_get_mask(scnview, &mask) == RES_OK);
    161   CHK(mask == S3D_TRACE);
    162 
    163   CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK);
    164   CHK(s3d_scene_clear(scn) == RES_OK);
    165 
    166   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    167 
    168   CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK);
    169   CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK);
    170   CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK);
    171   CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK);
    172   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    173 
    174   CHK(s3d_scene_attach_shape(scn2, shapes[1]) == RES_OK);
    175   CHK(s3d_scene_attach_shape(scn2, shapes[2]) == RES_OK);
    176   CHK(s3d_scene_attach_shape(scn3, shapes[1]) == RES_OK);
    177 
    178   CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK);
    179   CHK(n == 1);
    180   CHK(s3d_scene_get_shapes_count(scn2, &n) == RES_OK);
    181   CHK(n == 2);
    182   CHK(s3d_scene_get_shapes_count(scn3, &n) == RES_OK);
    183   CHK(n == 1);
    184 
    185   CHK(s3d_scene_view_create(scn2, S3D_SAMPLE|S3D_TRACE, &scnview2) == RES_OK);
    186   CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &scnview) == RES_OK);
    187   CHK(s3d_scene_view_create(scn3, S3D_SAMPLE, &scnview3) == RES_OK);
    188   CHK(s3d_scene_view_ref_put(scnview3) == RES_OK);
    189 
    190   CHK(s3d_scene_view_compute_area(NULL, NULL) == RES_BAD_ARG);
    191   CHK(s3d_scene_view_compute_area(scnview2, NULL) == RES_BAD_ARG);
    192   CHK(s3d_scene_view_compute_area(NULL, &area) == RES_BAD_ARG);
    193   CHK(s3d_scene_view_compute_area(scnview2, &area) == RES_OK);
    194   CHK(area == 0.f);
    195 
    196   CHK(s3d_scene_view_compute_volume(NULL, NULL) == RES_BAD_ARG);
    197   CHK(s3d_scene_view_compute_volume(scnview2, NULL) == RES_BAD_ARG);
    198   CHK(s3d_scene_view_compute_volume(NULL, &volume) == RES_BAD_ARG);
    199   CHK(s3d_scene_view_compute_volume(scnview2, &volume) == RES_OK);
    200   CHK(volume == 0.f);
    201 
    202   CHK(s3d_scene_view_primitives_count(NULL, NULL) == RES_BAD_ARG);
    203   CHK(s3d_scene_view_primitives_count(scnview2, NULL) == RES_BAD_ARG);
    204   CHK(s3d_scene_view_primitives_count(NULL, &nprims) == RES_BAD_ARG);
    205   CHK(s3d_scene_view_primitives_count(scnview2, &nprims) == RES_OK);
    206   CHK(nprims == 0);
    207 
    208   CHK(s3d_scene_view_get_aabb(NULL, NULL, NULL) == RES_BAD_ARG);
    209   CHK(s3d_scene_view_get_aabb(scnview2, NULL, NULL) == RES_BAD_ARG);
    210   CHK(s3d_scene_view_get_aabb(NULL, lower, NULL) == RES_BAD_ARG);
    211   CHK(s3d_scene_view_get_aabb(scnview2, lower, NULL) == RES_BAD_ARG);
    212   CHK(s3d_scene_view_get_aabb(NULL, NULL, upper) == RES_BAD_ARG);
    213   CHK(s3d_scene_view_get_aabb(scnview2, NULL, upper) == RES_BAD_ARG);
    214   CHK(s3d_scene_view_get_aabb(NULL, lower, upper) == RES_BAD_ARG);
    215   CHK(s3d_scene_view_get_aabb(scnview2, lower, upper) == RES_OK);
    216   CHK(lower[0] > upper[0]);
    217   CHK(lower[1] > upper[1]);
    218   CHK(lower[2] > upper[2]);
    219 
    220   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    221   CHK(s3d_scene_view_ref_put(scnview2) == RES_OK);
    222 
    223   CHK(s3d_scene_instantiate(scn2, shapes + 3) == RES_OK);
    224   CHK(s3d_scene_attach_shape(scn3, shapes[3]) == RES_OK);
    225   CHK(s3d_scene_get_shapes_count(scn3, &n) == RES_OK);
    226   CHK(n == 2);
    227   CHK(s3d_scene_view_create(scn3, S3D_SAMPLE|S3D_TRACE, &scnview3) == RES_BAD_ARG);
    228 
    229   CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK);
    230 
    231   CHK(s3d_shape_ref_put(shapes[0]) == RES_OK);
    232   CHK(s3d_shape_ref_put(shapes[1]) == RES_OK);
    233   CHK(s3d_shape_ref_put(shapes[2]) == RES_OK);
    234   CHK(s3d_shape_ref_put(shapes[3]) == RES_OK);
    235 
    236   CHK(s3d_scene_ref_get(NULL) == RES_BAD_ARG);
    237   CHK(s3d_scene_ref_get(scn) == RES_OK);
    238   CHK(s3d_scene_ref_put(NULL) == RES_BAD_ARG);
    239   CHK(s3d_scene_ref_put(scn) == RES_OK);
    240   CHK(s3d_scene_ref_put(scn) == RES_OK);
    241   CHK(s3d_scene_ref_put(scn2) == RES_OK);
    242   CHK(s3d_scene_ref_put(scn3) == RES_OK);
    243 
    244   CHK(s3d_scene_create(dev, &scn) == RES_OK);
    245   CHK(s3d_scene_create(dev, &scn2) == RES_OK);
    246 
    247   attribs.type = S3D_FLOAT3;
    248   attribs.usage = S3D_POSITION;
    249   attribs.get = cbox_get_position;
    250   CHK(s3d_shape_create_mesh(dev, shapes + 0) == RES_OK);
    251   CHK(s3d_mesh_setup_indexed_vertices(shapes[0], cbox_walls_ntris,
    252     cbox_get_ids, cbox_walls_nverts, &attribs, 1, data) == RES_OK);
    253   CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK);
    254 
    255   CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK);
    256   CHK(s3d_scene_view_compute_area(scnview, &area) == RES_OK);
    257   CHK(eq_epsf(area, 1532296.f, 1.e-6f) == 1);
    258   CHK(s3d_scene_view_primitives_count(scnview, &nprims) == RES_OK);
    259   CHK(nprims == 10);
    260   CHK(s3d_scene_view_get_aabb(scnview, lower, upper) == RES_OK);
    261   CHK(eq_epsf(lower[0], 0.f, 1.e-6f) == 1);
    262   CHK(eq_epsf(lower[1], 0.f, 1.e-6f) == 1);
    263   CHK(eq_epsf(lower[2], 0.f, 1.e-6f) == 1);
    264   CHK(eq_epsf(upper[0], 552.f, 1.e-6f) == 1);
    265   CHK(eq_epsf(upper[1], 559.f, 1.e-6f) == 1);
    266   CHK(eq_epsf(upper[2], 548.f, 1.e-6f) == 1);
    267 
    268   CHK(s3d_scene_instantiate(scn, shapes + 1) == RES_OK);
    269   CHK(s3d_scene_attach_shape(scn2, shapes[1]) == RES_OK);
    270 
    271   CHK(s3d_scene_view_create(scn2, S3D_GET_PRIMITIVE, &scnview2) == RES_OK);
    272   CHK(s3d_scene_view_compute_area(scnview2, &area) == RES_OK);
    273   CHK(eq_epsf(area, 1532296.f, 1.e-6f) == 1);
    274   CHK(s3d_scene_view_primitives_count(scnview2, &nprims) == RES_OK);
    275   CHK(nprims == 10);
    276   CHK(s3d_scene_view_get_aabb(scnview2, lower, upper) == RES_OK);
    277   CHK(eq_epsf(lower[0], 0.f, 1.e-6f) == 1);
    278   CHK(eq_epsf(lower[1], 0.f, 1.e-6f) == 1);
    279   CHK(eq_epsf(lower[2], 0.f, 1.e-6f) == 1);
    280   CHK(eq_epsf(upper[0], 552.f, 1.e-6f) == 1);
    281   CHK(eq_epsf(upper[1], 559.f, 1.e-6f) == 1);
    282   CHK(eq_epsf(upper[2], 548.f, 1.e-6f) == 1);
    283 
    284   CHK(s3d_scene_view_compute_area(scnview, &area) == RES_OK);
    285   CHK(eq_epsf(area, 1532296.f, 1.e-6f) == 1);
    286   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    287 
    288   CHK(s3d_scene_view_get_primitive(NULL, 11, NULL) == RES_BAD_ARG);
    289   CHK(s3d_scene_view_get_primitive(scnview2, 11, NULL) == RES_BAD_ARG);
    290   CHK(s3d_scene_view_get_primitive(NULL, 0, NULL) == RES_BAD_ARG);
    291   CHK(s3d_scene_view_get_primitive(scnview2, 0, NULL) == RES_BAD_ARG);
    292   CHK(s3d_scene_view_get_primitive(NULL, 11, prims + 0) == RES_BAD_ARG);
    293   CHK(s3d_scene_view_get_primitive(scnview2, 11, prims + 0) == RES_BAD_ARG);
    294   CHK(s3d_scene_view_get_primitive(NULL, 0, prims + 0) == RES_BAD_ARG);
    295 
    296   FOR_EACH(i, 0, nprims) {
    297     size_t j;
    298     CHK(s3d_scene_view_get_primitive(scnview2, (unsigned)i, prims + i) == RES_OK);
    299     CHK(S3D_PRIMITIVE_EQ(prims + i, &S3D_PRIMITIVE_NULL) == 0);
    300     CHK(prims[i].scene_prim_id == i);
    301     FOR_EACH(j, 0, i)
    302       CHK(S3D_PRIMITIVE_EQ(prims + i, prims + j) == 0);
    303   }
    304   CHK(s3d_scene_view_ref_put(scnview2) == RES_OK);
    305 
    306   attribs.type = S3D_FLOAT3;
    307   attribs.usage = S3D_POSITION;
    308   attribs.get = cube_get_pos;
    309   CHK(s3d_mesh_setup_indexed_vertices
    310     (shapes[0], cube_ntris, cube_get_ids, cube_nverts, &attribs, 1, NULL) == RES_OK);
    311 
    312   CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK);
    313   CHK(s3d_scene_view_compute_area(scnview, &area) == RES_OK);
    314   CHK(eq_epsf(area, 6.f, 1.e-6f) == 1);
    315   CHK(s3d_scene_view_compute_volume(scnview, &volume) == RES_OK);
    316   CHK(eq_epsf(volume, 1.f, 1.e-6f) == 1);
    317   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    318 
    319   CHK(s3d_shape_flip_surface(shapes[0]) == RES_OK);
    320   CHK(s3d_scene_view_create(scn, S3D_GET_PRIMITIVE, &scnview) == RES_OK);
    321   CHK(s3d_scene_view_compute_volume(scnview, &volume) == RES_OK);
    322   CHK(eq_epsf(volume, -1.f, 1.e-6f) == 1);
    323   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    324 
    325   CHK(s3d_scene_get_device(NULL, NULL) == RES_BAD_ARG);
    326   CHK(s3d_scene_get_device(scn, NULL) == RES_BAD_ARG);
    327   CHK(s3d_scene_get_device(NULL, &dev2) == RES_BAD_ARG);
    328   CHK(s3d_scene_get_device(scn, &dev2) == RES_OK);
    329   CHK(dev2 == dev);
    330   CHK(s3d_scene_get_device(scn2, &dev2) == RES_OK);
    331   CHK(dev2 == dev);
    332 
    333   CHK(s3d_scene_ref_put(scn) == RES_OK);
    334   CHK(s3d_scene_ref_put(scn2) == RES_OK);
    335   CHK(s3d_shape_ref_put(shapes[0]) == RES_OK);
    336   CHK(s3d_shape_ref_put(shapes[1]) == RES_OK);
    337 
    338   CHK(s3d_device_ref_put(dev) == RES_OK);;
    339 
    340   check_memory_allocator(&allocator);
    341   mem_shutdown_proxy_allocator(&allocator);
    342   CHK(mem_allocated_size() == 0);
    343   return 0;
    344 }
    345