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