test_s3d_scene.c (13204B)
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 #include "test_s3d_cbox.h" 19 20 #include <rsys/math.h> 21 22 static const float cube_verts[] = { 23 5.f, 5.f, 5.f, 24 6.f, 5.f, 5.f, 25 5.f, 6.f, 5.f, 26 6.f, 6.f, 5.f, 27 5.f, 5.f, 6.f, 28 6.f, 5.f, 6.f, 29 5.f, 6.f, 6.f, 30 6.f, 6.f, 6.f 31 }; 32 static const unsigned cube_nverts = sizeof(cube_verts) / (sizeof(float)*3); 33 34 /* Front faces are CW. The normals point into the cube */ 35 static const unsigned cube_ids[] = { 36 0, 2, 1, 1, 2, 3, /* Front */ 37 0, 4, 2, 2, 4, 6, /* Left */ 38 4, 5, 6, 6, 5, 7, /* Back */ 39 3, 7, 1, 1, 7, 5, /* Right */ 40 2, 6, 3, 3, 6, 7, /* Top */ 41 0, 1, 4, 4, 1, 5 /* Bottom */ 42 }; 43 static const unsigned cube_ntris = sizeof(cube_ids) / (sizeof(unsigned)*3); 44 45 static void 46 cube_get_ids(const unsigned itri, unsigned ids[3], void* data) 47 { 48 const unsigned id = itri * 3; 49 CHK(data == NULL); 50 CHK(ids != NULL); 51 CHK(itri < cube_ntris); 52 ids[0] = cube_ids[id + 0]; 53 ids[1] = cube_ids[id + 1]; 54 ids[2] = cube_ids[id + 2]; 55 } 56 57 static void 58 cube_get_pos(const unsigned ivert, float pos[3], void* data) 59 { 60 const unsigned i = ivert*3; 61 CHK(data == NULL); 62 CHK(pos != NULL); 63 CHK(ivert < cube_nverts); 64 pos[0] = cube_verts[i + 0]; 65 pos[1] = cube_verts[i + 1]; 66 pos[2] = cube_verts[i + 2]; 67 } 68 69 int 70 main(int argc, char** argv) 71 { 72 struct mem_allocator allocator; 73 struct s3d_primitive prims[10]; 74 struct s3d_device* dev, *dev2; 75 struct s3d_scene* scn; 76 struct s3d_scene* scn2; 77 struct s3d_scene* scn3; 78 struct s3d_scene_view* scnview; 79 struct s3d_scene_view* scnview2; 80 struct s3d_scene_view* scnview3; 81 struct s3d_vertex_data attribs; 82 struct s3d_shape* shapes[4]; 83 const size_t nshapes = sizeof(shapes)/sizeof(struct s3d_shape*); 84 void* data = (void*)&cbox_walls_desc; 85 size_t i, n; 86 size_t nprims; 87 float area, volume, lower[3], upper[3]; 88 unsigned id; 89 int mask; 90 (void)argc, (void)argv; 91 92 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 93 94 CHK(s3d_device_create(NULL, &allocator, 1, &dev) == RES_OK); 95 FOR_EACH(i, 0, nshapes) 96 CHK(s3d_shape_create_mesh(dev, shapes + i) == RES_OK); 97 98 CHK(s3d_scene_create(NULL, NULL) == RES_BAD_ARG); 99 CHK(s3d_scene_create(dev, NULL) == RES_BAD_ARG); 100 CHK(s3d_scene_create(NULL, &scn) == RES_BAD_ARG); 101 CHK(s3d_scene_create(dev, &scn) == RES_OK); 102 CHK(s3d_scene_create(dev, &scn2) == RES_OK); 103 CHK(s3d_scene_create(dev, &scn3) == RES_OK); 104 105 CHK(s3d_scene_get_shapes_count(NULL, NULL) == RES_BAD_ARG); 106 CHK(s3d_scene_get_shapes_count(scn, NULL) == RES_BAD_ARG); 107 CHK(s3d_scene_get_shapes_count(NULL, &n) == RES_BAD_ARG); 108 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 109 CHK(n == 0); 110 111 CHK(s3d_scene_attach_shape(NULL, NULL) == RES_BAD_ARG); 112 CHK(s3d_scene_attach_shape(scn, NULL) == RES_BAD_ARG); 113 CHK(s3d_scene_attach_shape(NULL, shapes[0]) == RES_BAD_ARG); 114 CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK); 115 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 116 CHK(n == 1); 117 CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK); 118 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 119 CHK(n == 1); 120 121 CHK(s3d_scene_detach_shape(NULL, NULL) == RES_BAD_ARG); 122 CHK(s3d_scene_detach_shape(scn, NULL) == RES_BAD_ARG); 123 CHK(s3d_scene_detach_shape(NULL, shapes[0]) == RES_BAD_ARG); 124 CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK); 125 CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_BAD_ARG); 126 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 127 CHK(n == 0); 128 129 FOR_EACH(i, 1, nshapes) { 130 CHK(s3d_scene_attach_shape(scn, shapes[i]) == RES_OK); 131 CHK(s3d_shape_ref_put(shapes[i]) == RES_OK); 132 } 133 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 134 CHK(n == nshapes - 1); 135 136 CHK(s3d_scene_instantiate(NULL, NULL) == RES_BAD_ARG); 137 CHK(s3d_scene_instantiate(scn, NULL) == RES_BAD_ARG); 138 CHK(s3d_scene_instantiate(NULL, shapes + 1) == RES_BAD_ARG); 139 CHK(s3d_scene_instantiate(scn, shapes + 1) == RES_OK); 140 141 CHK(s3d_shape_get_id(NULL, NULL) == RES_BAD_ARG); 142 CHK(s3d_shape_get_id(shapes[1], NULL) == RES_BAD_ARG); 143 CHK(s3d_shape_get_id(NULL, &id) == RES_BAD_ARG); 144 CHK(s3d_shape_get_id(shapes[1], &id) == RES_OK); 145 CHK(id != S3D_INVALID_ID); 146 147 CHK(s3d_scene_clear(NULL) == RES_BAD_ARG); 148 CHK(s3d_scene_clear(scn) == RES_OK); 149 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 150 CHK(n == 0); 151 CHK(s3d_scene_clear(scn) == RES_OK); 152 CHK(s3d_scene_instantiate(scn, shapes + 2) == RES_OK); 153 CHK(s3d_scene_attach_shape(scn, shapes[2]) == RES_BAD_ARG); 154 155 CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK); 156 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 157 CHK(n == 1); 158 159 CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK); 160 CHK(s3d_scene_view_get_mask(scnview, &mask) == RES_OK); 161 CHK(mask == S3D_TRACE); 162 163 CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK); 164 CHK(s3d_scene_clear(scn) == RES_OK); 165 166 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 167 168 CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK); 169 CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK); 170 CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK); 171 CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK); 172 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 173 174 CHK(s3d_scene_attach_shape(scn2, shapes[1]) == RES_OK); 175 CHK(s3d_scene_attach_shape(scn2, shapes[2]) == RES_OK); 176 CHK(s3d_scene_attach_shape(scn3, shapes[1]) == RES_OK); 177 178 CHK(s3d_scene_get_shapes_count(scn, &n) == RES_OK); 179 CHK(n == 1); 180 CHK(s3d_scene_get_shapes_count(scn2, &n) == RES_OK); 181 CHK(n == 2); 182 CHK(s3d_scene_get_shapes_count(scn3, &n) == RES_OK); 183 CHK(n == 1); 184 185 CHK(s3d_scene_view_create(scn2, S3D_SAMPLE|S3D_TRACE, &scnview2) == RES_OK); 186 CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &scnview) == RES_OK); 187 CHK(s3d_scene_view_create(scn3, S3D_SAMPLE, &scnview3) == RES_OK); 188 CHK(s3d_scene_view_ref_put(scnview3) == RES_OK); 189 190 CHK(s3d_scene_view_compute_area(NULL, NULL) == RES_BAD_ARG); 191 CHK(s3d_scene_view_compute_area(scnview2, NULL) == RES_BAD_ARG); 192 CHK(s3d_scene_view_compute_area(NULL, &area) == RES_BAD_ARG); 193 CHK(s3d_scene_view_compute_area(scnview2, &area) == RES_OK); 194 CHK(area == 0.f); 195 196 CHK(s3d_scene_view_compute_volume(NULL, NULL) == RES_BAD_ARG); 197 CHK(s3d_scene_view_compute_volume(scnview2, NULL) == RES_BAD_ARG); 198 CHK(s3d_scene_view_compute_volume(NULL, &volume) == RES_BAD_ARG); 199 CHK(s3d_scene_view_compute_volume(scnview2, &volume) == RES_OK); 200 CHK(volume == 0.f); 201 202 CHK(s3d_scene_view_primitives_count(NULL, NULL) == RES_BAD_ARG); 203 CHK(s3d_scene_view_primitives_count(scnview2, NULL) == RES_BAD_ARG); 204 CHK(s3d_scene_view_primitives_count(NULL, &nprims) == RES_BAD_ARG); 205 CHK(s3d_scene_view_primitives_count(scnview2, &nprims) == RES_OK); 206 CHK(nprims == 0); 207 208 CHK(s3d_scene_view_get_aabb(NULL, NULL, NULL) == RES_BAD_ARG); 209 CHK(s3d_scene_view_get_aabb(scnview2, NULL, NULL) == RES_BAD_ARG); 210 CHK(s3d_scene_view_get_aabb(NULL, lower, NULL) == RES_BAD_ARG); 211 CHK(s3d_scene_view_get_aabb(scnview2, lower, NULL) == RES_BAD_ARG); 212 CHK(s3d_scene_view_get_aabb(NULL, NULL, upper) == RES_BAD_ARG); 213 CHK(s3d_scene_view_get_aabb(scnview2, NULL, upper) == RES_BAD_ARG); 214 CHK(s3d_scene_view_get_aabb(NULL, lower, upper) == RES_BAD_ARG); 215 CHK(s3d_scene_view_get_aabb(scnview2, lower, upper) == RES_OK); 216 CHK(lower[0] > upper[0]); 217 CHK(lower[1] > upper[1]); 218 CHK(lower[2] > upper[2]); 219 220 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 221 CHK(s3d_scene_view_ref_put(scnview2) == RES_OK); 222 223 CHK(s3d_scene_instantiate(scn2, shapes + 3) == RES_OK); 224 CHK(s3d_scene_attach_shape(scn3, shapes[3]) == RES_OK); 225 CHK(s3d_scene_get_shapes_count(scn3, &n) == RES_OK); 226 CHK(n == 2); 227 CHK(s3d_scene_view_create(scn3, S3D_SAMPLE|S3D_TRACE, &scnview3) == RES_BAD_ARG); 228 229 CHK(s3d_scene_detach_shape(scn, shapes[0]) == RES_OK); 230 231 CHK(s3d_shape_ref_put(shapes[0]) == RES_OK); 232 CHK(s3d_shape_ref_put(shapes[1]) == RES_OK); 233 CHK(s3d_shape_ref_put(shapes[2]) == RES_OK); 234 CHK(s3d_shape_ref_put(shapes[3]) == RES_OK); 235 236 CHK(s3d_scene_ref_get(NULL) == RES_BAD_ARG); 237 CHK(s3d_scene_ref_get(scn) == RES_OK); 238 CHK(s3d_scene_ref_put(NULL) == RES_BAD_ARG); 239 CHK(s3d_scene_ref_put(scn) == RES_OK); 240 CHK(s3d_scene_ref_put(scn) == RES_OK); 241 CHK(s3d_scene_ref_put(scn2) == RES_OK); 242 CHK(s3d_scene_ref_put(scn3) == RES_OK); 243 244 CHK(s3d_scene_create(dev, &scn) == RES_OK); 245 CHK(s3d_scene_create(dev, &scn2) == RES_OK); 246 247 attribs.type = S3D_FLOAT3; 248 attribs.usage = S3D_POSITION; 249 attribs.get = cbox_get_position; 250 CHK(s3d_shape_create_mesh(dev, shapes + 0) == RES_OK); 251 CHK(s3d_mesh_setup_indexed_vertices(shapes[0], cbox_walls_ntris, 252 cbox_get_ids, cbox_walls_nverts, &attribs, 1, data) == RES_OK); 253 CHK(s3d_scene_attach_shape(scn, shapes[0]) == RES_OK); 254 255 CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK); 256 CHK(s3d_scene_view_compute_area(scnview, &area) == RES_OK); 257 CHK(eq_epsf(area, 1532296.f, 1.e-6f) == 1); 258 CHK(s3d_scene_view_primitives_count(scnview, &nprims) == RES_OK); 259 CHK(nprims == 10); 260 CHK(s3d_scene_view_get_aabb(scnview, lower, upper) == RES_OK); 261 CHK(eq_epsf(lower[0], 0.f, 1.e-6f) == 1); 262 CHK(eq_epsf(lower[1], 0.f, 1.e-6f) == 1); 263 CHK(eq_epsf(lower[2], 0.f, 1.e-6f) == 1); 264 CHK(eq_epsf(upper[0], 552.f, 1.e-6f) == 1); 265 CHK(eq_epsf(upper[1], 559.f, 1.e-6f) == 1); 266 CHK(eq_epsf(upper[2], 548.f, 1.e-6f) == 1); 267 268 CHK(s3d_scene_instantiate(scn, shapes + 1) == RES_OK); 269 CHK(s3d_scene_attach_shape(scn2, shapes[1]) == RES_OK); 270 271 CHK(s3d_scene_view_create(scn2, S3D_GET_PRIMITIVE, &scnview2) == RES_OK); 272 CHK(s3d_scene_view_compute_area(scnview2, &area) == RES_OK); 273 CHK(eq_epsf(area, 1532296.f, 1.e-6f) == 1); 274 CHK(s3d_scene_view_primitives_count(scnview2, &nprims) == RES_OK); 275 CHK(nprims == 10); 276 CHK(s3d_scene_view_get_aabb(scnview2, lower, upper) == RES_OK); 277 CHK(eq_epsf(lower[0], 0.f, 1.e-6f) == 1); 278 CHK(eq_epsf(lower[1], 0.f, 1.e-6f) == 1); 279 CHK(eq_epsf(lower[2], 0.f, 1.e-6f) == 1); 280 CHK(eq_epsf(upper[0], 552.f, 1.e-6f) == 1); 281 CHK(eq_epsf(upper[1], 559.f, 1.e-6f) == 1); 282 CHK(eq_epsf(upper[2], 548.f, 1.e-6f) == 1); 283 284 CHK(s3d_scene_view_compute_area(scnview, &area) == RES_OK); 285 CHK(eq_epsf(area, 1532296.f, 1.e-6f) == 1); 286 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 287 288 CHK(s3d_scene_view_get_primitive(NULL, 11, NULL) == RES_BAD_ARG); 289 CHK(s3d_scene_view_get_primitive(scnview2, 11, NULL) == RES_BAD_ARG); 290 CHK(s3d_scene_view_get_primitive(NULL, 0, NULL) == RES_BAD_ARG); 291 CHK(s3d_scene_view_get_primitive(scnview2, 0, NULL) == RES_BAD_ARG); 292 CHK(s3d_scene_view_get_primitive(NULL, 11, prims + 0) == RES_BAD_ARG); 293 CHK(s3d_scene_view_get_primitive(scnview2, 11, prims + 0) == RES_BAD_ARG); 294 CHK(s3d_scene_view_get_primitive(NULL, 0, prims + 0) == RES_BAD_ARG); 295 296 FOR_EACH(i, 0, nprims) { 297 size_t j; 298 CHK(s3d_scene_view_get_primitive(scnview2, (unsigned)i, prims + i) == RES_OK); 299 CHK(S3D_PRIMITIVE_EQ(prims + i, &S3D_PRIMITIVE_NULL) == 0); 300 CHK(prims[i].scene_prim_id == i); 301 FOR_EACH(j, 0, i) 302 CHK(S3D_PRIMITIVE_EQ(prims + i, prims + j) == 0); 303 } 304 CHK(s3d_scene_view_ref_put(scnview2) == RES_OK); 305 306 attribs.type = S3D_FLOAT3; 307 attribs.usage = S3D_POSITION; 308 attribs.get = cube_get_pos; 309 CHK(s3d_mesh_setup_indexed_vertices 310 (shapes[0], cube_ntris, cube_get_ids, cube_nverts, &attribs, 1, NULL) == RES_OK); 311 312 CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK); 313 CHK(s3d_scene_view_compute_area(scnview, &area) == RES_OK); 314 CHK(eq_epsf(area, 6.f, 1.e-6f) == 1); 315 CHK(s3d_scene_view_compute_volume(scnview, &volume) == RES_OK); 316 CHK(eq_epsf(volume, 1.f, 1.e-6f) == 1); 317 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 318 319 CHK(s3d_shape_flip_surface(shapes[0]) == RES_OK); 320 CHK(s3d_scene_view_create(scn, S3D_GET_PRIMITIVE, &scnview) == RES_OK); 321 CHK(s3d_scene_view_compute_volume(scnview, &volume) == RES_OK); 322 CHK(eq_epsf(volume, -1.f, 1.e-6f) == 1); 323 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 324 325 CHK(s3d_scene_get_device(NULL, NULL) == RES_BAD_ARG); 326 CHK(s3d_scene_get_device(scn, NULL) == RES_BAD_ARG); 327 CHK(s3d_scene_get_device(NULL, &dev2) == RES_BAD_ARG); 328 CHK(s3d_scene_get_device(scn, &dev2) == RES_OK); 329 CHK(dev2 == dev); 330 CHK(s3d_scene_get_device(scn2, &dev2) == RES_OK); 331 CHK(dev2 == dev); 332 333 CHK(s3d_scene_ref_put(scn) == RES_OK); 334 CHK(s3d_scene_ref_put(scn2) == RES_OK); 335 CHK(s3d_shape_ref_put(shapes[0]) == RES_OK); 336 CHK(s3d_shape_ref_put(shapes[1]) == RES_OK); 337 338 CHK(s3d_device_ref_put(dev) == RES_OK);; 339 340 check_memory_allocator(&allocator); 341 mem_shutdown_proxy_allocator(&allocator); 342 CHK(mem_allocated_size() == 0); 343 return 0; 344 } 345