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