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_primitive.c (11366B)


      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_cbox.h"
     18 #include "test_s3d_utils.h"
     19 
     20 #include <rsys/float2.h>
     21 #include <rsys/float3.h>
     22 #include <rsys/math.h>
     23 
     24 static const float plane_verts[] = {
     25   0.f, 0.f, 0.f,
     26   1.f, 0.f, 0.f,
     27   1.f, 1.f, 0.f,
     28   0.f, 1.f, 0.f
     29 };
     30 static const unsigned plane_nverts = sizeof(plane_verts) / (sizeof(float)*3);
     31 
     32 static const unsigned plane_ids[] = { 0, 1, 2, 2, 3, 0 };
     33 static const unsigned plane_ntris = sizeof(plane_ids) / (sizeof(unsigned)*3);
     34 
     35 static void
     36 plane_get_ids(const unsigned itri, unsigned ids[3], void* data)
     37 {
     38   const unsigned id = itri * 3;
     39   (void)data;
     40   CHK(ids != NULL);
     41   CHK(itri < plane_ntris);
     42   ids[0] = plane_ids[id + 0];
     43   ids[1] = plane_ids[id + 1];
     44   ids[2] = plane_ids[id + 2];
     45 }
     46 
     47 static void
     48 plane_get_pos(const unsigned ivert, float pos[3], void* data)
     49 {
     50   const unsigned i = ivert*3;
     51   (void)data;
     52   CHK(pos != NULL);
     53   CHK(ivert < plane_nverts);
     54   pos[0] = plane_verts[i + 0];
     55   pos[1] = plane_verts[i + 1];
     56   pos[2] = plane_verts[i + 2];
     57 }
     58 
     59 static void
     60 plane_get_uv(const unsigned ivert, float uv[2], void* data)
     61 {
     62   const unsigned i = ivert*3;
     63   (void)data;
     64   CHK(uv != NULL);
     65   CHK(ivert < plane_nverts);
     66   uv[0] = -plane_verts[i + 0];
     67   uv[1] = -plane_verts[i + 1];
     68 }
     69 
     70 int
     71 main(int argc, char** argv)
     72 {
     73   struct mem_allocator allocator;
     74   struct s3d_device* dev;
     75   struct s3d_scene* scn;
     76   struct s3d_scene_view* scnview;
     77   struct s3d_shape* walls;
     78   struct s3d_shape* plane;
     79   struct s3d_attrib attr;
     80   struct s3d_primitive prim = S3D_PRIMITIVE_NULL;
     81   struct s3d_vertex_data attribs[2];
     82   struct cbox_desc desc;
     83   size_t nprims;
     84   size_t i;
     85   float transform[12];
     86   float vec[3];
     87   float uv[2];
     88   float area;
     89   unsigned ntris, nverts;
     90   unsigned walls_id;
     91   char b;
     92   (void)argc, (void)argv;
     93 
     94   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     95 
     96   CHK(s3d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
     97   CHK(s3d_scene_create(dev, &scn) == RES_OK);
     98   CHK(s3d_shape_create_mesh(dev, &walls) == RES_OK);
     99   CHK(s3d_shape_create_mesh(dev, &plane) == RES_OK);
    100   CHK(s3d_shape_get_id(walls, &walls_id) == RES_OK);
    101   CHK(s3d_scene_attach_shape(scn, walls) == RES_OK);
    102 
    103   attribs[1].usage = S3D_ATTRIB_0;
    104   attribs[1].type = S3D_FLOAT2;
    105   attribs[1].get = plane_get_uv;
    106 
    107   attribs[0].usage = S3D_POSITION;
    108   attribs[0].type = S3D_FLOAT3;
    109   attribs[0].get = cbox_get_position;
    110 
    111   ntris = cbox_walls_ntris;
    112   nverts = cbox_walls_nverts;
    113   desc.vertices = cbox_walls;
    114   desc.indices = cbox_walls_ids;
    115   CHK(s3d_mesh_setup_indexed_vertices
    116     (walls, ntris, cbox_get_ids, nverts, attribs, 1, &desc) == RES_OK);
    117 
    118   attribs[0].get = plane_get_pos;
    119   CHK(s3d_mesh_setup_indexed_vertices
    120     (plane, plane_ntris, plane_get_ids, plane_nverts, attribs, 2, NULL) == RES_OK);
    121 
    122   CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &scnview) == RES_OK);
    123   CHK(s3d_scene_view_sample(scnview, 0, 0, 0, &prim, uv) == RES_OK);
    124   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    125 
    126   CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, NULL, NULL) == RES_BAD_ARG);
    127   CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, NULL, NULL) == RES_BAD_ARG);
    128   CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, uv, NULL) == RES_BAD_ARG);
    129   CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, uv, NULL) == RES_BAD_ARG);
    130   CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, NULL, &attr) == RES_BAD_ARG);
    131   CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, NULL, &attr) == RES_BAD_ARG);
    132   CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, uv, &attr) == RES_BAD_ARG);
    133   CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, uv, &attr) == RES_BAD_ARG);
    134 
    135   CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, NULL, NULL) == RES_BAD_ARG);
    136   CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, NULL, NULL) == RES_BAD_ARG);
    137   CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, uv, NULL) == RES_BAD_ARG);
    138   CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, uv, NULL) == RES_BAD_ARG);
    139   CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, NULL, &attr) == RES_BAD_ARG);
    140   CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, NULL, &attr) == RES_BAD_ARG);
    141   CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, uv, &attr) == RES_BAD_ARG);
    142   CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, uv, &attr) == RES_OK);
    143   CHK(attr.type == S3D_FLOAT3);
    144   CHK(attr.usage == S3D_POSITION);
    145   CHK(s3d_primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, uv, &attr) == RES_OK);
    146   CHK(attr.type == S3D_FLOAT3);
    147   CHK(attr.usage == S3D_GEOMETRY_NORMAL);
    148   CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIB_0, uv, &attr) == RES_BAD_ARG);
    149   CHK(s3d_primitive_get_attrib(&S3D_PRIMITIVE_NULL, S3D_POSITION, uv, &attr) == RES_BAD_ARG);
    150 
    151   CHK(s3d_primitive_has_attrib(NULL, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    152   CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    153   CHK(s3d_primitive_has_attrib(NULL, S3D_POSITION, NULL) == RES_BAD_ARG);
    154   CHK(s3d_primitive_has_attrib(&prim, S3D_POSITION, NULL) == RES_BAD_ARG);
    155   CHK(s3d_primitive_has_attrib(NULL, S3D_ATTRIBS_COUNT__, &b) == RES_BAD_ARG);
    156   CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIBS_COUNT__, &b) == RES_BAD_ARG);
    157   CHK(s3d_primitive_has_attrib(NULL, S3D_POSITION, &b) == RES_BAD_ARG);
    158   CHK(s3d_primitive_has_attrib(&prim, S3D_POSITION, &b) == RES_OK);
    159   CHK(b == 1);
    160   CHK(s3d_primitive_has_attrib(&prim, S3D_GEOMETRY_NORMAL, &b) == RES_OK);
    161   CHK(b == 1);
    162   CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIB_0, &b) == RES_OK);
    163   CHK(b == 0);
    164 
    165   CHK(s3d_primitive_get_transform(NULL, NULL) == RES_BAD_ARG);
    166   CHK(s3d_primitive_get_transform(&prim, NULL) == RES_BAD_ARG);
    167   CHK(s3d_primitive_get_transform(NULL, transform) == RES_BAD_ARG);
    168   CHK(s3d_primitive_get_transform(&prim, transform) == RES_OK);
    169   CHK(f3_eq(transform + 0, f3(vec, 1.f, 0.f, 0.f)) == 1);
    170   CHK(f3_eq(transform + 3, f3(vec, 0.f, 1.f, 0.f)) == 1);
    171   CHK(f3_eq(transform + 6, f3(vec, 0.f, 0.f, 1.f)) == 1);
    172   CHK(f3_eq(transform + 9, f3(vec, 0.f, 0.f, 0.f)) == 1);
    173 
    174   CHK(s3d_scene_clear(scn) == RES_OK);
    175   CHK(s3d_scene_attach_shape(scn, plane) == RES_OK);
    176 
    177   CHK(s3d_scene_view_create(scn, S3D_GET_PRIMITIVE, &scnview) == RES_OK);
    178   CHK(s3d_scene_view_primitives_count(scnview, &nprims) == RES_OK);
    179   CHK(nprims == 2);
    180   CHK(s3d_scene_view_get_primitive(scnview, 0, &prim) == RES_OK);
    181   CHK(S3D_PRIMITIVE_EQ(&prim, &S3D_PRIMITIVE_NULL) == 0);
    182   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    183 
    184   CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIB_0, &b) == RES_OK);
    185   CHK(b == 1);
    186   CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIB_1, &b) == RES_OK);
    187   CHK(b == 0);
    188 
    189   CHK(s3d_primitive_compute_area(NULL, NULL) == RES_BAD_ARG);
    190   CHK(s3d_primitive_compute_area(&prim, NULL) == RES_BAD_ARG);
    191   CHK(s3d_primitive_compute_area(NULL, &area) == RES_BAD_ARG);
    192   CHK(s3d_primitive_compute_area(&prim, &area) == RES_OK);
    193   CHK(eq_epsf(area, 0.5f, 1.e-6f) == 1);
    194 
    195   CHK(s3d_primitive_sample(NULL,  1.f, 1.f, NULL) == RES_BAD_ARG);
    196   CHK(s3d_primitive_sample(&prim, 1.f, 1.f, NULL) == RES_BAD_ARG);
    197   CHK(s3d_primitive_sample(NULL, 0.f, 1.f, NULL) == RES_BAD_ARG);
    198   CHK(s3d_primitive_sample(&prim, 0.f, 1.f, NULL) == RES_BAD_ARG);
    199   CHK(s3d_primitive_sample(NULL,  1.f, 0.f, NULL) == RES_BAD_ARG);
    200   CHK(s3d_primitive_sample(&prim, 1.f, 0.f, NULL) == RES_BAD_ARG);
    201   CHK(s3d_primitive_sample(NULL, 0.f, 0.f, NULL) == RES_BAD_ARG);
    202   CHK(s3d_primitive_sample(&prim, 0.f, 0.f, NULL) == RES_BAD_ARG);
    203   CHK(s3d_primitive_sample(NULL,  1.f, 1.f, uv) == RES_BAD_ARG);
    204   CHK(s3d_primitive_sample(&prim, 1.f, 1.f, uv) == RES_BAD_ARG);
    205   CHK(s3d_primitive_sample(NULL, 0.f, 1.f, uv) == RES_BAD_ARG);
    206   CHK(s3d_primitive_sample(&prim, 0.f, 1.f, uv) == RES_BAD_ARG);
    207   CHK(s3d_primitive_sample(NULL,  1.f, 0.f, uv) == RES_BAD_ARG);
    208   CHK(s3d_primitive_sample(&prim, 1.f, 0.f, uv) == RES_BAD_ARG);
    209   CHK(s3d_primitive_sample(NULL, 0.f, 0.f, uv) == RES_BAD_ARG);
    210   CHK(s3d_primitive_sample(&prim, 0.f, 0.f, uv) == RES_OK);
    211 
    212   FOR_EACH(i, 0, 4096) {
    213     CHK(s3d_primitive_sample
    214       (&prim, rand_canonic(), rand_canonic(), uv) == RES_OK);
    215     CHK(uv[0] >= 0.f);
    216     CHK(uv[0] <= 1.f);
    217     CHK(uv[1] >= 0.f);
    218     CHK(uv[1] <= 1.f);
    219   }
    220 
    221   #define GET_VERTEX_ATTR s3d_triangle_get_vertex_attrib
    222   CHK(GET_VERTEX_ATTR(NULL, 3, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG);
    223   CHK(GET_VERTEX_ATTR(&prim, 3, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG);
    224   CHK(GET_VERTEX_ATTR(NULL, 0, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG);
    225   CHK(GET_VERTEX_ATTR(&prim, 0, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG);
    226   CHK(GET_VERTEX_ATTR(NULL, 3, S3D_POSITION, NULL) == RES_BAD_ARG);
    227   CHK(GET_VERTEX_ATTR(&prim, 3, S3D_POSITION, NULL) == RES_BAD_ARG);
    228   CHK(GET_VERTEX_ATTR(NULL, 0, S3D_POSITION, NULL) == RES_BAD_ARG);
    229   CHK(GET_VERTEX_ATTR(&prim, 0, S3D_POSITION, NULL) == RES_BAD_ARG);
    230   CHK(GET_VERTEX_ATTR(NULL, 3, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG);
    231   CHK(GET_VERTEX_ATTR(&prim, 3, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG);
    232   CHK(GET_VERTEX_ATTR(NULL, 0, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG);
    233   CHK(GET_VERTEX_ATTR(&prim, 0, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG);
    234   CHK(GET_VERTEX_ATTR(NULL, 3, S3D_POSITION, &attr) == RES_BAD_ARG);
    235   CHK(GET_VERTEX_ATTR(&prim, 3, S3D_POSITION, &attr) == RES_BAD_ARG);
    236   CHK(GET_VERTEX_ATTR(NULL, 0, S3D_POSITION, &attr) == RES_BAD_ARG);
    237 
    238   CHK(GET_VERTEX_ATTR(&prim, 0, S3D_POSITION, &attr) == RES_OK);
    239   CHK(attr.type == S3D_FLOAT3);
    240   CHK(f3_eq_eps(attr.value, plane_verts + plane_ids[0]*3, 1.e-6f) == 1);
    241   CHK(GET_VERTEX_ATTR(&prim, 1, S3D_POSITION, &attr) == RES_OK);
    242   CHK(attr.type == S3D_FLOAT3);
    243   CHK(f3_eq_eps(attr.value, plane_verts + plane_ids[1]*3, 1.e-6f) == 1);
    244   CHK(GET_VERTEX_ATTR(&prim, 2, S3D_POSITION, &attr) == RES_OK);
    245   CHK(attr.type == S3D_FLOAT3);
    246   CHK(f3_eq_eps(attr.value, plane_verts + plane_ids[2]*3, 1.e-6f) == 1);
    247 
    248   CHK(GET_VERTEX_ATTR(&prim, 0, S3D_ATTRIB_0, &attr) == RES_OK);
    249   CHK(attr.type == S3D_FLOAT2);
    250   f2_minus(uv, plane_verts + plane_ids[0]*3);
    251   CHK(f2_eq_eps(attr.value, uv, 1.e-6f) == 1);
    252   CHK(GET_VERTEX_ATTR(&prim, 1, S3D_ATTRIB_0, &attr) == RES_OK);
    253   CHK(attr.type == S3D_FLOAT2);
    254   f2_minus(uv, plane_verts + plane_ids[1]*3);
    255   CHK(f2_eq_eps(attr.value, uv, 1.e-6f) == 1);
    256   CHK(GET_VERTEX_ATTR(&prim, 2, S3D_ATTRIB_0, &attr) == RES_OK);
    257   CHK(attr.type == S3D_FLOAT2);
    258   f2_minus(uv, plane_verts + plane_ids[2]*3);
    259   CHK(f2_eq_eps(attr.value, uv, 1.e-6f) == 1);
    260   #undef GET_VERTEX_ATTR
    261 
    262   CHK(s3d_device_ref_put(dev) == RES_OK);
    263   CHK(s3d_scene_ref_put(scn) == RES_OK);
    264   CHK(s3d_shape_ref_put(walls) == RES_OK);
    265   CHK(s3d_shape_ref_put(plane) == RES_OK);
    266 
    267   check_memory_allocator(&allocator);
    268   mem_shutdown_proxy_allocator(&allocator);
    269   CHK(mem_allocated_size() == 0);
    270   return 0;
    271 }
    272