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


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