test_s2d_trace_ray.c (8684B)
1 /* Copyright (C) 2016-2021, 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 "s2d.h" 17 #include "test_s2d_utils.h" 18 19 #include <rsys/float2.h> 20 21 struct ray_data { 22 struct s2d_primitive prim; 23 float ray_org[2]; 24 float ray_dir[2]; 25 float ray_range[2]; 26 }; 27 28 static int 29 filter_hit 30 (const struct s2d_hit* hit, 31 const float org[2], 32 const float dir[2], 33 const float range[2], 34 void* ray_data, 35 void* filter_data) 36 { 37 struct ray_data* data = ray_data; 38 CHK(hit != NULL); 39 CHK(org != NULL); 40 CHK(dir != NULL); 41 CHK(range != NULL); 42 CHK((intptr_t)filter_data == 0xDEADBEEF); 43 if(!ray_data) return 0; 44 CHK(f2_eq(data->ray_org, org)); 45 CHK(f2_eq(data->ray_dir, dir)); 46 CHK(f2_eq(data->ray_range, range)); 47 return S2D_PRIMITIVE_EQ(&data->prim, &hit->prim); 48 } 49 50 int 51 main(int argc, char** argv) 52 { 53 struct ray_data ray_data; 54 struct s2d_device* dev; 55 struct s2d_shape* shape; 56 struct s2d_scene* scn; 57 struct s2d_scene_view* scnview; 58 struct s2d_vertex_data vdata; 59 struct s2d_hit hit; 60 struct s2d_primitive prim, prim2; 61 struct mem_allocator allocator; 62 float org[2], dir[3], range[2]; 63 float N[3] = {0.f, 0.f, 0.f}; 64 (void)argc, (void)argv; 65 66 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 67 68 CHK(s2d_device_create(NULL, &allocator, 1, &dev) == RES_OK); 69 CHK(s2d_shape_create_line_segments(dev, &shape) == RES_OK); 70 CHK(s2d_scene_create(dev, &scn) == RES_OK); 71 72 vdata.type = S2D_FLOAT2; 73 vdata.usage = S2D_POSITION; 74 vdata.get = line_segments_get_position; 75 CHK(s2d_line_segments_setup_indexed_vertices 76 (shape, square_nsegs, line_segments_get_ids, square_nverts, &vdata, 1, 77 (void*)&square_desc) == RES_OK); 78 79 #define SET_FILTER_FUNC s2d_line_segments_set_hit_filter_function 80 CHK(SET_FILTER_FUNC(NULL, NULL, NULL) == RES_BAD_ARG); 81 CHK(SET_FILTER_FUNC(shape, NULL, NULL) == RES_OK); 82 CHK(SET_FILTER_FUNC(NULL, filter_hit, NULL) == RES_BAD_ARG); 83 CHK(SET_FILTER_FUNC(shape, filter_hit, NULL) == RES_OK); 84 CHK(SET_FILTER_FUNC(shape, filter_hit, (void*)0xDEADBEEF) == RES_OK); 85 #undef SET_FILTER_FUNC 86 87 CHK(s2d_scene_attach_shape(scn, shape) == RES_OK); 88 89 f2(org, 10.f, 10.f); 90 f2(dir, 0.f, -1.f); 91 f2(range, 0, FLT_MAX); 92 93 CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK); 94 95 #define RT s2d_scene_view_trace_ray 96 CHK(RT(NULL, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG); 97 CHK(RT(scnview, NULL, NULL, NULL, NULL, NULL) == RES_BAD_ARG); 98 CHK(RT(NULL, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG); 99 CHK(RT(scnview, org, NULL, NULL, NULL, NULL) == RES_BAD_ARG); 100 CHK(RT(NULL, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG); 101 CHK(RT(scnview, NULL, dir, NULL, NULL, NULL) == RES_BAD_ARG); 102 CHK(RT(NULL, org, dir, NULL, NULL, NULL) == RES_BAD_ARG); 103 CHK(RT(scnview, org, dir, NULL, NULL, NULL) == RES_BAD_ARG); 104 CHK(RT(NULL, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG); 105 CHK(RT(scnview, NULL, NULL, range, NULL, NULL) == RES_BAD_ARG); 106 CHK(RT(NULL, org, NULL, range, NULL, NULL) == RES_BAD_ARG); 107 CHK(RT(scnview, org, NULL, range, NULL, NULL) == RES_BAD_ARG); 108 CHK(RT(NULL, NULL, dir, range, NULL, NULL) == RES_BAD_ARG); 109 CHK(RT(scnview, NULL, dir, range, NULL, NULL) == RES_BAD_ARG); 110 CHK(RT(NULL, org, dir, range, NULL, NULL) == RES_BAD_ARG); 111 CHK(RT(scnview, org, dir, range, NULL, NULL) == RES_BAD_ARG); 112 CHK(RT(NULL, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG); 113 CHK(RT(scnview, NULL, NULL, NULL, NULL, &hit) == RES_BAD_ARG); 114 CHK(RT(NULL, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG); 115 CHK(RT(scnview, org, NULL, NULL, NULL, &hit) == RES_BAD_ARG); 116 CHK(RT(NULL, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG); 117 CHK(RT(scnview, NULL, dir, NULL, NULL, &hit) == RES_BAD_ARG); 118 CHK(RT(NULL, org, dir, NULL, NULL, &hit) == RES_BAD_ARG); 119 CHK(RT(scnview, org, dir, NULL, NULL, &hit) == RES_BAD_ARG); 120 CHK(RT(NULL, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG); 121 CHK(RT(scnview, NULL, NULL, range, NULL, &hit) == RES_BAD_ARG); 122 CHK(RT(NULL, org, NULL, range, NULL, &hit) == RES_BAD_ARG); 123 CHK(RT(scnview, org, NULL, range, NULL, &hit) == RES_BAD_ARG); 124 CHK(RT(NULL, NULL, dir, range, NULL, &hit) == RES_BAD_ARG); 125 CHK(RT(scnview, NULL, dir, range, NULL, &hit) == RES_BAD_ARG); 126 CHK(RT(NULL, org, dir, range, NULL, &hit) == RES_BAD_ARG); 127 128 f2(dir, 0.f, -1.f); 129 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 130 CHK(S2D_HIT_NONE(&hit) == 0); 131 CHK(hit.prim.prim_id == 0); 132 f2_normalize(N, hit.normal); 133 CHK(f2_eq_eps(N, f2(dir, 0.f, 1.f), 1.e-6f) == 1); 134 CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1); 135 CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1); 136 137 prim = hit.prim; 138 139 f2(dir, 0.f, -1.f); 140 range[1] = 0.5f; 141 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 142 CHK(S2D_HIT_NONE(&hit) == 1); 143 range[1] = FLT_MAX; 144 145 146 f2(dir, 0.f, -1.f); 147 f2_set(ray_data.ray_org, org); 148 f2_set(ray_data.ray_dir, dir); 149 f2_set(ray_data.ray_range, range); 150 ray_data.prim = prim; 151 CHK(RT(scnview, org, dir, range, &ray_data, &hit) == RES_OK); 152 CHK(S2D_HIT_NONE(&hit) == 1); 153 154 f2(dir, -1.f, 0.f); 155 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 156 CHK(S2D_HIT_NONE(&hit) == 0); 157 CHK(hit.prim.prim_id == 1); 158 f2_normalize(N, hit.normal); 159 CHK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f) == 1); 160 CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1); 161 CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1); 162 163 f2(dir, 0.f, 1.f); 164 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 165 CHK(S2D_HIT_NONE(&hit) == 0); 166 CHK(hit.prim.prim_id == 2); 167 f2_normalize(N, hit.normal); 168 CHK(f2_eq_eps(N, f2(dir, 0.f, -1.f), 1.e-6f) == 1); 169 CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1); 170 CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1); 171 172 prim2 = hit.prim; 173 174 f2(org, 10.f, 12.f); 175 f2(dir, 0.f, -1.f); 176 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 177 CHK(S2D_HIT_NONE(&hit) == 0); 178 CHK(S2D_PRIMITIVE_EQ(&hit.prim, &prim2) == 1); 179 180 f2_set(ray_data.ray_org, org); 181 f2_set(ray_data.ray_dir, dir); 182 f2_set(ray_data.ray_range, range); 183 ray_data.prim = prim2; 184 CHK(RT(scnview, org, dir, range, &ray_data, &hit) == RES_OK); 185 CHK(S2D_HIT_NONE(&hit) == 0); 186 CHK(S2D_PRIMITIVE_EQ(&hit.prim, &prim) == 1); 187 188 f2_splat(org, 10.f); 189 f2(dir, 1.f, 0.f); 190 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 191 CHK(S2D_HIT_NONE(&hit) == 0); 192 CHK(hit.prim.prim_id == 3); 193 f2_normalize(N, hit.normal); 194 CHK(f2_eq_eps(N, f2(dir, -1.f, 0.f), 1.e-6f) == 1); 195 CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1); 196 CHK(eq_epsf(hit.distance, 1.0f, 1.e-6f) == 1); 197 198 f2(range, 1.f, -1.f); 199 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 200 CHK(S2D_HIT_NONE(&hit) == 1); 201 202 f2(dir, 1.f, 1.f); 203 f2(range, 0.f, FLT_MAX); 204 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_BAD_ARG); 205 206 CHK(s2d_scene_view_ref_put(scnview) == RES_OK); 207 208 CHK(s2d_scene_view_create(scn, S2D_TRACE, &scnview) == RES_OK); 209 f2(dir, 0.75f, -1.f); 210 f2_normalize(dir, dir); 211 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 212 CHK(S2D_HIT_NONE(&hit) == 0); 213 CHK(eq_epsf(hit.u, 0.125f, 1.e-6f) == 1); 214 CHK(eq_epsf(hit.distance, 1.25, 1.E-6f) == 1); 215 216 f2(dir, -1.f, 0.25f); 217 f2_normalize(dir, dir); 218 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 219 CHK(S2D_HIT_NONE(&hit) == 0); 220 CHK(eq_epsf(hit.u, 0.625, 1.e-6f) == 1); 221 CHK(eq_epsf(hit.distance, (float)sqrt(1.0625f), 1e-6f) == 1); 222 223 f2(org, 8.75f, 10.f); 224 f2(dir, -1, 0.f); 225 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 226 CHK(S2D_HIT_NONE(&hit) == 1); 227 228 f2(dir, 1, 0.f); 229 CHK(RT(scnview, org, dir, range, NULL, &hit) == RES_OK); 230 CHK(S2D_HIT_NONE(&hit) == 0); 231 CHK(hit.prim.prim_id == 1); 232 f2_normalize(N, hit.normal); 233 CHK(f2_eq_eps(N, f2(dir, 1.f, 0.f), 1.e-6f) == 1); 234 CHK(eq_epsf(hit.u, 0.5f, 1.e-6f) == 1); 235 CHK(eq_epsf(hit.distance, 0.25f, 1.e-6f) == 1); 236 237 CHK(s2d_scene_view_ref_put(scnview) == RES_OK); 238 239 CHK(s2d_device_ref_put(dev) == RES_OK); 240 CHK(s2d_shape_ref_put(shape) == RES_OK); 241 CHK(s2d_scene_ref_put(scn) == RES_OK); 242 243 check_memory_allocator(&allocator); 244 mem_shutdown_proxy_allocator(&allocator); 245 CHK(mem_allocated_size() == 0); 246 247 return 0; 248 } 249