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_seams.c (5198B)


      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 
     19 #include <rsys/mem_allocator.h>
     20 #include <rsys/float33.h>
     21 #include <rsys/double33.h>
     22 
     23 struct desc {
     24   const float* vertices;
     25   const unsigned* indices;
     26 };
     27 
     28 /*******************************************************************************
     29  * Callbacks
     30  ******************************************************************************/
     31 static INLINE void
     32 get_ids(const unsigned itri, unsigned ids[3], void* data)
     33 {
     34   const unsigned id = itri * 3;
     35   struct desc* desc = data;
     36   CHK(desc != NULL);
     37   CHK(ids != NULL);
     38   ids[0] = desc->indices[id + 0];
     39   ids[1] = desc->indices[id + 1];
     40   ids[2] = desc->indices[id + 2];
     41 }
     42 
     43 static INLINE void
     44 get_position(const unsigned ivert, float position[3], void* data)
     45 {
     46   struct desc* desc = data;
     47   CHK(desc != NULL);
     48   CHK(position != NULL);
     49   position[0] = desc->vertices[ivert * 3 + 0];
     50   position[1] = desc->vertices[ivert * 3 + 1];
     51   position[2] = desc->vertices[ivert * 3 + 2];
     52 }
     53 
     54 static INLINE void
     55 get_normal(const unsigned ivert, float normal[3], void* data)
     56 {
     57   (void) ivert, (void) data;
     58   CHK(normal != NULL);
     59   normal[0] = 1.f;
     60   normal[1] = 0.f;
     61   normal[2] = 0.f;
     62 }
     63 
     64 static INLINE void
     65 get_uv(const unsigned ivert, float uv[2], void* data)
     66 {
     67   (void) ivert, (void) data;
     68   CHK(uv != NULL);
     69   uv[0] = -1.f;
     70   uv[1] = 1.f;
     71 }
     72 
     73 static INLINE void
     74 get_polygon_vertices(const size_t ivert, double position[2], void* ctx)
     75 {
     76   const double* verts = ctx;
     77   CHK(position != NULL);
     78   CHK(ctx != NULL);
     79   position[0] = verts[ivert * 2 + 0];
     80   position[1] = verts[ivert * 2 + 1];
     81 }
     82 
     83 static const float SQUARE_EDGES__ [] = {
     84   -0.1f, -0.1f, 0.f,
     85    0.1f, -0.1f, 0.f,
     86    0.1f,  0.1f, 0.f,
     87   -0.1f,  0.1f, 0.f
     88 };
     89 static const unsigned SQUARE_NVERTS__ = sizeof(SQUARE_EDGES__) / (sizeof(float)*3);
     90 static const unsigned SQUARE_TRG_IDS__ [] = { 0, 2, 1, 2, 0, 3 };
     91 static const unsigned SQUARE_NTRIS__ = sizeof(SQUARE_TRG_IDS__) / (sizeof(unsigned)*3);
     92 static const struct desc SQUARE_DESC__ = { SQUARE_EDGES__, SQUARE_TRG_IDS__ };
     93 
     94 static int
     95 check_ray(int use_double)
     96 {
     97   struct mem_allocator allocator;
     98   struct s3d_device* dev;
     99   struct s3d_hit hit;
    100   struct s3d_scene* scn;
    101   struct s3d_scene* scn2;
    102   struct s3d_scene_view* scnview;
    103   struct s3d_shape* square;
    104   struct s3d_shape* inst;
    105   struct s3d_vertex_data attribs;
    106   float transformf[12];
    107   double transform[12];
    108   float range[2] = { 0.f, FLT_MAX };
    109   float org[3] = {
    110     3.3492994308471680f, -9.7470426559448242f, 2.6555661803570274f
    111   };
    112   float dir[3] = {
    113     -0.26465030351986046f, 0.77017831656345948f, 0.58033229924097962f
    114   };
    115   float pos[3];
    116 
    117   if(use_double) {
    118     d33_rotation_pitch(transform, PI);
    119     f33_set_d33(transformf, transform);
    120   } else {
    121     f33_rotation_pitch(transformf, (float)PI);
    122   }
    123   f3_splat(transformf + 9, 0);
    124   transformf[11] = 10;
    125 
    126   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
    127 
    128   CHK(s3d_device_create(NULL, &allocator, 1, &dev) == RES_OK);
    129   CHK(s3d_scene_create(dev, &scn) == RES_OK);
    130   CHK(s3d_scene_create(dev, &scn2) == RES_OK);
    131 
    132   attribs.usage = S3D_POSITION;
    133   attribs.type = S3D_FLOAT3;
    134   attribs.get = get_position;
    135 
    136   CHK(s3d_shape_create_mesh(dev, &square) == RES_OK);
    137   CHK(s3d_mesh_setup_indexed_vertices(square, SQUARE_NTRIS__, get_ids,
    138     SQUARE_NVERTS__, &attribs, 1, (void*) &SQUARE_DESC__) == RES_OK);
    139   CHK(s3d_scene_attach_shape(scn, square) == RES_OK);
    140   s3d_scene_instantiate(scn, &inst);
    141   CHK(s3d_instance_set_transform(inst, transformf) == RES_OK);
    142   CHK(s3d_scene_attach_shape(scn2, inst) == RES_OK);
    143 
    144   CHK(s3d_scene_view_create(scn2, S3D_TRACE, &scnview) == RES_OK);
    145   CHK(s3d_scene_view_trace_ray(scnview, org, dir, range, NULL, &hit) == RES_OK);
    146   printf("\nRaytrace using %s: ", use_double ? "double" : "float");
    147   if(!S3D_HIT_NONE(&hit)) {
    148     f3_add(pos, org, f3_mulf(pos, dir, hit.distance));
    149     printf("Hit at [%g %g %g]\n",SPLIT3(pos));
    150   } else {
    151     printf("No hit\n");
    152   }
    153   CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
    154   CHK(s3d_scene_ref_put(scn) == RES_OK);
    155   CHK(s3d_scene_ref_put(scn2) == RES_OK);
    156   CHK(s3d_device_ref_put(dev) == RES_OK);
    157   CHK(s3d_shape_ref_put(square) == RES_OK);
    158   CHK(s3d_shape_ref_put(inst) == RES_OK);
    159 
    160   check_memory_allocator(&allocator);
    161   mem_shutdown_proxy_allocator(&allocator);
    162   CHK(mem_allocated_size() == 0);
    163 
    164   return S3D_HIT_NONE(&hit) ? RES_UNKNOWN_ERR : RES_OK;
    165 }
    166 
    167 int
    168 main(int argc, char** argv)
    169 {
    170   (void)argc, (void)argv;
    171   CHK(check_ray(1) == RES_OK);
    172   CHK(check_ray(0) == RES_OK);
    173   return 0;
    174 }
    175