star-3d

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

test_s3d_shape.c (16015B)


      1 /* Copyright (C) 2015-2023, 2026 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This file is part of Star-3D.
      4  *
      5  * Star-3D is free software: you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation, either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * Star-3D is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with Star-3D. If not, see <http://www.gnu.org/licenses/>. */
     17 
     18 #include "s3d.h"
     19 #include "test_s3d_cbox.h"
     20 #include "test_s3d_utils.h"
     21 
     22 #include <rsys/float3.h>
     23 #include <rsys/math.h>
     24 
     25 static int
     26 filter_none
     27   (const struct s3d_hit* hit,
     28    const float org[3],
     29    const float dir[3],
     30    const float range[2],
     31    void* ray_data,
     32    void* filter_data)
     33 {
     34   (void)hit, (void)org, (void)dir, (void)range, (void)ray_data, (void)filter_data;
     35   return 0;
     36 }
     37 
     38 int
     39 main(int argc, char** argv)
     40 {
     41   struct mem_allocator allocator;
     42   struct s3d_device* dev;
     43   struct s3d_shape* shape;
     44   struct s3d_shape* shape_copy;
     45   struct s3d_shape* inst;
     46   struct s3d_scene* scn;
     47   struct s3d_vertex_data attribs[4];
     48   struct s3d_attrib attr;
     49   unsigned nverts, ntris;
     50   unsigned ids[3];
     51   float pos[3];
     52   float trans[12];
     53   const unsigned cbox_ntris = cbox_walls_ntris;
     54   const unsigned cbox_nverts = cbox_walls_nverts;
     55   unsigned id;
     56   void* data = (void*)&cbox_walls_desc;
     57   char c;
     58   (void)argc, (void)argv;
     59 
     60   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     61 
     62   CHK(s3d_device_create(NULL, &allocator, 0, &dev) == RES_OK);
     63   CHK(s3d_scene_create(dev, &scn) == RES_OK);
     64 
     65   CHK(s3d_shape_create_mesh(NULL, NULL) == RES_BAD_ARG);
     66   CHK(s3d_shape_create_mesh(dev, NULL) == RES_BAD_ARG);
     67   CHK(s3d_shape_create_mesh(NULL, &shape) == RES_BAD_ARG);
     68   CHK(s3d_shape_create_mesh(dev, &shape) == RES_OK);
     69 
     70   CHK(s3d_shape_get_id(NULL, NULL) == RES_BAD_ARG);
     71   CHK(s3d_shape_get_id(shape, NULL) == RES_BAD_ARG);
     72   CHK(s3d_shape_get_id(NULL, &id) == RES_BAD_ARG);
     73   CHK(s3d_shape_get_id(shape, &id) == RES_OK);
     74   CHK(id != S3D_INVALID_ID);
     75 
     76   CHK(s3d_scene_attach_shape(NULL, NULL) == RES_BAD_ARG);
     77   CHK(s3d_scene_attach_shape(scn, NULL) == RES_BAD_ARG);
     78   CHK(s3d_scene_attach_shape(NULL, shape) == RES_BAD_ARG);
     79   CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
     80 
     81   CHK(s3d_scene_detach_shape(NULL, NULL) == RES_BAD_ARG);
     82   CHK(s3d_scene_detach_shape(scn, NULL) == RES_BAD_ARG);
     83   CHK(s3d_scene_detach_shape(NULL, shape) == RES_BAD_ARG);
     84   CHK(s3d_scene_detach_shape(scn, shape) == RES_OK);
     85 
     86   attribs[0].type = S3D_FLOAT3;
     87   attribs[0].usage = S3D_POSITION;
     88   attribs[0].get = cbox_get_position;
     89   CHK(s3d_mesh_setup_indexed_vertices
     90     (NULL, 0, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     91   CHK(s3d_mesh_setup_indexed_vertices
     92     (shape, 0, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     93   CHK(s3d_mesh_setup_indexed_vertices
     94     (NULL, cbox_ntris, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     95   CHK(s3d_mesh_setup_indexed_vertices
     96     (shape, cbox_ntris, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     97   CHK(s3d_mesh_setup_indexed_vertices
     98     (NULL, 0, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
     99   CHK(s3d_mesh_setup_indexed_vertices
    100     (shape, 0, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
    101   CHK(s3d_mesh_setup_indexed_vertices
    102     (NULL, cbox_ntris, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
    103   CHK(s3d_mesh_setup_indexed_vertices
    104     (shape, cbox_ntris, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
    105   CHK(s3d_mesh_setup_indexed_vertices
    106     (NULL, 0, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    107   CHK(s3d_mesh_setup_indexed_vertices
    108     (shape, 0, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    109   CHK(s3d_mesh_setup_indexed_vertices
    110     (NULL, cbox_ntris, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    111   CHK(s3d_mesh_setup_indexed_vertices
    112     (shape, cbox_ntris, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    113   CHK(s3d_mesh_setup_indexed_vertices
    114     (NULL, 0, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    115   CHK(s3d_mesh_setup_indexed_vertices
    116     (shape, 0, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    117   CHK(s3d_mesh_setup_indexed_vertices
    118     (NULL, cbox_ntris, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    119   CHK(s3d_mesh_setup_indexed_vertices
    120     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    121   CHK(s3d_mesh_setup_indexed_vertices
    122     (NULL, 0, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    123   CHK(s3d_mesh_setup_indexed_vertices
    124     (shape, 0, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    125   CHK(s3d_mesh_setup_indexed_vertices
    126     (NULL, cbox_ntris, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    127   CHK(s3d_mesh_setup_indexed_vertices
    128     (shape, cbox_ntris, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    129   CHK(s3d_mesh_setup_indexed_vertices
    130     (NULL, 0, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    131   CHK(s3d_mesh_setup_indexed_vertices
    132     (shape, 0, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    133   CHK(s3d_mesh_setup_indexed_vertices
    134     (NULL, cbox_ntris, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    135   CHK(s3d_mesh_setup_indexed_vertices
    136     (shape, cbox_ntris, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    137   CHK(s3d_mesh_setup_indexed_vertices
    138     (NULL, 0, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    139   CHK(s3d_mesh_setup_indexed_vertices
    140     (shape, 0, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    141   CHK(s3d_mesh_setup_indexed_vertices
    142     (NULL, cbox_ntris, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    143   CHK(s3d_mesh_setup_indexed_vertices
    144     (shape, cbox_ntris, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    145   CHK(s3d_mesh_setup_indexed_vertices
    146     (NULL, 0, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    147   CHK(s3d_mesh_setup_indexed_vertices
    148     (shape, 0, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    149   CHK(s3d_mesh_setup_indexed_vertices
    150     (NULL, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    151   CHK(s3d_mesh_setup_indexed_vertices
    152     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_OK);
    153   CHK(s3d_mesh_setup_indexed_vertices
    154     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 0, data) == RES_BAD_ARG);
    155 
    156   attribs[0] = S3D_VERTEX_DATA_NULL;
    157   CHK(s3d_mesh_setup_indexed_vertices
    158     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    159 
    160   attribs[0].type = S3D_FLOAT3;
    161   attribs[0].usage = S3D_POSITION;
    162   attribs[0].get = S3D_KEEP;
    163   CHK(s3d_mesh_setup_indexed_vertices
    164     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_OK);
    165 
    166   attribs[0].get = cbox_get_position;
    167   CHK(s3d_mesh_setup_indexed_vertices
    168     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 1, data) == RES_OK);
    169 
    170   attribs[0].type = S3D_FLOAT3;
    171   attribs[0].usage = S3D_ATTRIB_0;
    172   attribs[0].get = cbox_get_normal;
    173   CHK(s3d_mesh_setup_indexed_vertices
    174     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    175 
    176   attribs[1].type = S3D_FLOAT3;
    177   attribs[1].usage = S3D_POSITION;
    178   attribs[1].get = S3D_KEEP;
    179   CHK(s3d_mesh_setup_indexed_vertices
    180     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 2, data) == RES_OK);
    181 
    182   attribs[2].type = S3D_FLOAT2;
    183   attribs[2].usage = S3D_ATTRIB_2;
    184   attribs[2].get = cbox_get_uv;
    185   CHK(s3d_mesh_setup_indexed_vertices
    186     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_OK);
    187 
    188   attribs[0].get = S3D_KEEP;
    189   attribs[1].get = S3D_KEEP;
    190   attribs[2].get = S3D_KEEP;
    191   CHK(s3d_mesh_setup_indexed_vertices
    192     (shape, 2, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_BAD_ARG);
    193   CHK(s3d_mesh_setup_indexed_vertices
    194     (shape, cbox_ntris, S3D_KEEP, cbox_nverts+1, attribs, 3, data) == RES_BAD_ARG);
    195   CHK(s3d_mesh_setup_indexed_vertices
    196     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_OK);
    197 
    198   attribs[2].type = S3D_FLOAT3;
    199   CHK(s3d_mesh_setup_indexed_vertices
    200     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_BAD_ARG);
    201 
    202   attribs[0].get = cbox_get_position;
    203   CHK(s3d_mesh_setup_indexed_vertices
    204     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 2, data) == RES_OK);
    205 
    206   CHK(s3d_mesh_get_vertices_count(NULL, NULL) == RES_BAD_ARG);
    207   CHK(s3d_mesh_get_vertices_count(shape, NULL) == RES_BAD_ARG);
    208   CHK(s3d_mesh_get_vertices_count(NULL, &nverts) == RES_BAD_ARG);
    209   CHK(s3d_mesh_get_vertices_count(shape, &nverts) == RES_OK);
    210   CHK(nverts == cbox_nverts);
    211 
    212   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    213   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    214   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    215   CHK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    216   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_POSITION, NULL) == RES_BAD_ARG);
    217   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_POSITION, NULL) == RES_BAD_ARG);
    218   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_POSITION, NULL) == RES_BAD_ARG);
    219   CHK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_POSITION, NULL) == RES_BAD_ARG);
    220   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    221   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    222   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    223   CHK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    224   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_POSITION, &attr) == RES_BAD_ARG);
    225   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_POSITION, &attr) == RES_BAD_ARG);
    226   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_POSITION, &attr) == RES_BAD_ARG);
    227   FOR_EACH(id, 0, nverts) {
    228     cbox_get_position(id, pos, data);
    229 
    230     CHK(s3d_mesh_get_vertex_attrib(shape, id, S3D_POSITION, &attr) == RES_OK);
    231     CHK(attr.type == S3D_FLOAT3);
    232     CHK(attr.usage == S3D_POSITION);
    233     CHK(f3_eq_eps(attr.value, pos, 1.e-6f) == 1);
    234 
    235     CHK(s3d_mesh_get_vertex_attrib(shape, id, S3D_ATTRIB_0, &attr) == RES_OK);
    236     CHK(attr.type == S3D_FLOAT3);
    237     CHK(attr.usage == S3D_ATTRIB_0);
    238     CHK(f3_eq_eps(attr.value, pos, 1.e-6f) == 1);
    239   }
    240   CHK(s3d_mesh_get_vertex_attrib(shape, id, S3D_ATTRIB_1, &attr) == RES_BAD_ARG);
    241 
    242   CHK(s3d_mesh_get_triangles_count(NULL, NULL) == RES_BAD_ARG);
    243   CHK(s3d_mesh_get_triangles_count(shape, NULL) == RES_BAD_ARG);
    244   CHK(s3d_mesh_get_triangles_count(NULL, &ntris) == RES_BAD_ARG);
    245   CHK(s3d_mesh_get_triangles_count(shape, &ntris) == RES_OK);
    246   CHK(ntris == cbox_ntris);
    247 
    248   CHK(s3d_mesh_get_triangle_indices(NULL, ntris, NULL) == RES_BAD_ARG);
    249   CHK(s3d_mesh_get_triangle_indices(shape, ntris, NULL) == RES_BAD_ARG);
    250   CHK(s3d_mesh_get_triangle_indices(NULL, 0, NULL) == RES_BAD_ARG);
    251   CHK(s3d_mesh_get_triangle_indices(shape, 0, NULL) == RES_BAD_ARG);
    252   CHK(s3d_mesh_get_triangle_indices(NULL, ntris, ids) == RES_BAD_ARG);
    253   CHK(s3d_mesh_get_triangle_indices(shape, ntris, ids) == RES_BAD_ARG);
    254   CHK(s3d_mesh_get_triangle_indices(NULL, 0, ids) == RES_BAD_ARG);
    255 
    256   FOR_EACH(id, 0, ntris) {
    257     unsigned indices[3];
    258     CHK(s3d_mesh_get_triangle_indices(shape, id, ids) == RES_OK);
    259     cbox_get_ids(id, indices, data);
    260     CHK(ids[0] == indices[0]);
    261     CHK(ids[1] == indices[1]);
    262     CHK(ids[2] == indices[2]);
    263   }
    264 
    265   CHK(s3d_shape_is_enabled(NULL, NULL) == RES_BAD_ARG);
    266   CHK(s3d_shape_is_enabled(shape, NULL) == RES_BAD_ARG);
    267   CHK(s3d_shape_is_enabled(NULL, &c) == RES_BAD_ARG);
    268   CHK(s3d_shape_is_enabled(shape, &c) == RES_OK);
    269   CHK(c != 0);
    270 
    271   CHK(s3d_shape_enable(NULL, 0) == RES_BAD_ARG);
    272   CHK(s3d_shape_enable(shape, 0) == RES_OK);
    273   CHK(s3d_shape_is_enabled(shape, &c) == RES_OK);
    274   CHK(c == 0);
    275 
    276   CHK(s3d_shape_flip_surface(NULL) == RES_BAD_ARG);
    277   CHK(s3d_shape_flip_surface(shape) == RES_OK);
    278   CHK(s3d_shape_flip_surface(shape) == RES_OK);
    279 
    280   CHK(s3d_mesh_set_hit_filter_function(NULL, NULL, NULL) == RES_BAD_ARG);
    281   CHK(s3d_mesh_set_hit_filter_function(shape, NULL, NULL) == RES_OK);
    282   CHK(s3d_mesh_set_hit_filter_function(NULL, filter_none, NULL) == RES_BAD_ARG);
    283   CHK(s3d_mesh_set_hit_filter_function(shape, filter_none, NULL) == RES_OK);
    284 
    285   CHK(s3d_mesh_get_hit_filter_data(NULL, NULL) == RES_BAD_ARG);
    286   CHK(s3d_mesh_get_hit_filter_data(shape, NULL) == RES_BAD_ARG);
    287   CHK(s3d_mesh_get_hit_filter_data(NULL, &data) == RES_BAD_ARG);
    288   CHK(s3d_mesh_get_hit_filter_data(shape, &data) == RES_OK);
    289   CHK(data == NULL);
    290 
    291   CHK(s3d_mesh_set_hit_filter_function(shape, NULL, NULL) == RES_OK);
    292   CHK(s3d_mesh_get_hit_filter_data(shape, &data) == RES_OK);
    293   CHK(data == NULL);
    294   CHK(s3d_mesh_set_hit_filter_function
    295     (shape, filter_none, (void*)((uintptr_t)0xDEADBEEF)) == RES_OK);
    296   CHK(s3d_mesh_get_hit_filter_data(shape, &data) == RES_OK);
    297   CHK((uintptr_t)data == 0xDEADBEEF);
    298 
    299   CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
    300 
    301   CHK(s3d_scene_instantiate(scn, &inst) == RES_OK);
    302 
    303   CHK(s3d_instance_set_position(NULL, NULL) == RES_BAD_ARG);
    304   CHK(s3d_instance_set_position(inst, NULL) == RES_BAD_ARG);
    305   CHK(s3d_instance_set_position(NULL, pos) == RES_BAD_ARG);
    306   CHK(s3d_instance_set_position(inst, pos) == RES_OK);
    307   CHK(s3d_instance_set_position(shape, pos) == RES_BAD_ARG);
    308 
    309   CHK(s3d_instance_translate(NULL, -1, NULL) == RES_BAD_ARG);
    310   CHK(s3d_instance_translate(inst, -1, NULL) == RES_BAD_ARG);
    311   CHK(s3d_instance_translate(NULL, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    312   CHK(s3d_instance_translate(inst, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    313   CHK(s3d_instance_translate(NULL, -1, pos) == RES_BAD_ARG);
    314   CHK(s3d_instance_translate(inst, -1, pos) == RES_BAD_ARG);
    315   CHK(s3d_instance_translate(NULL, S3D_LOCAL_TRANSFORM, pos) == RES_BAD_ARG);
    316   CHK(s3d_instance_translate(inst, S3D_LOCAL_TRANSFORM, pos) == RES_OK);
    317   CHK(s3d_instance_translate(inst, S3D_WORLD_TRANSFORM, pos) == RES_OK);
    318   CHK(s3d_instance_translate(shape, S3D_WORLD_TRANSFORM, pos) == RES_BAD_ARG);
    319 
    320   CHK(s3d_instance_transform(NULL, -1, NULL) == RES_BAD_ARG);
    321   CHK(s3d_instance_transform(inst, -1, NULL) == RES_BAD_ARG);
    322   CHK(s3d_instance_transform(NULL, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    323   CHK(s3d_instance_transform(inst, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    324   CHK(s3d_instance_transform(NULL, -1, trans) == RES_BAD_ARG);
    325   CHK(s3d_instance_transform(inst, -1, trans) == RES_BAD_ARG);
    326   CHK(s3d_instance_transform(NULL, S3D_LOCAL_TRANSFORM, trans) == RES_BAD_ARG);
    327   CHK(s3d_instance_transform(inst, S3D_LOCAL_TRANSFORM, trans) == RES_OK);
    328   CHK(s3d_instance_transform(inst, S3D_WORLD_TRANSFORM, trans) == RES_OK);
    329   CHK(s3d_instance_transform(shape, S3D_LOCAL_TRANSFORM, trans) == RES_BAD_ARG);
    330 
    331   CHK(s3d_instance_set_transform(NULL, NULL) == RES_BAD_ARG);
    332   CHK(s3d_instance_set_transform(inst, NULL) == RES_BAD_ARG);
    333   CHK(s3d_instance_set_transform(NULL, trans) == RES_BAD_ARG);
    334   CHK(s3d_instance_set_transform(shape, trans) == RES_BAD_ARG);
    335   CHK(s3d_instance_set_transform(inst, trans) == RES_OK);
    336 
    337   CHK(s3d_shape_flip_surface(inst) == RES_OK);
    338 
    339   CHK(s3d_shape_create_mesh(dev, &shape_copy) == RES_OK);
    340   CHK(s3d_mesh_copy(NULL, NULL) == RES_BAD_ARG);
    341   CHK(s3d_mesh_copy(shape, NULL) == RES_BAD_ARG);
    342   CHK(s3d_mesh_copy(NULL, shape_copy) == RES_BAD_ARG);
    343   CHK(s3d_mesh_copy(shape, shape_copy) == RES_OK);
    344 
    345   CHK(s3d_shape_ref_get(NULL) == RES_BAD_ARG);
    346   CHK(s3d_shape_ref_get(shape) == RES_OK);
    347   CHK(s3d_shape_ref_put(NULL) == RES_BAD_ARG);
    348   CHK(s3d_shape_ref_put(shape) == RES_OK);
    349   CHK(s3d_shape_ref_put(shape) == RES_OK);
    350   CHK(s3d_shape_ref_put(inst) == RES_OK);
    351   CHK(s3d_shape_ref_put(shape_copy) == RES_OK);
    352   CHK(s3d_scene_ref_put(scn) == RES_OK);
    353 
    354   CHK(s3d_device_ref_put(dev) == RES_OK);;
    355 
    356   check_memory_allocator(&allocator);
    357   mem_shutdown_proxy_allocator(&allocator);
    358   CHK(mem_allocated_size() == 0);
    359   return 0;
    360 }
    361