test_aw_obj.c (22519B)
1 /* Copyright (C) 2014-2017, 2020-2023 Vincent Forest (vaplv@free.fr) 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 Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "aw.h" 17 18 #include <rsys/double3.h> 19 #include <rsys/double4.h> 20 #include <rsys/logger.h> 21 #include <rsys/mem_allocator.h> 22 23 #include <string.h> 24 25 static void 26 test_plane(struct aw_obj* obj) 27 { 28 static const char* plane_obj = 29 "mtllib master.mtl" 30 "\n" 31 "g\n" 32 "o plane\n" 33 "v 0.0000 2.0000 0.0000\n" 34 "v 0.0000 0.0000 0.0000\n" 35 "v 2.0000 0.0000 0.0000\n" 36 "v 2.0000 2.0000 0.0000\n" 37 "vt 0.0000 1.0000 0.0000\n" 38 "vt 0.0000 0.0000 0.0000\n" 39 "vt 1.0000 0.0000 0.0000\n" 40 "vt 1.0000 1.0000 0.0000\n" 41 "# 4 vertices\n" 42 "\n" 43 "usemtl wood\n" 44 "f 1/1 2/2 3/3 4/4\n" 45 "# 1 element\n"; 46 double v4[4]; 47 struct aw_obj_desc desc; 48 struct aw_obj_face face; 49 struct aw_obj_named_group group; 50 struct aw_obj_named_group mtl; 51 struct aw_obj_vertex vertex; 52 struct aw_obj_vertex_data vdata; 53 const double* data = NULL; 54 FILE* file; 55 const char* mtllib; 56 57 CHK(obj != NULL); 58 59 file = fopen("test_obj_plane.obj", "w"); 60 CHK(file != NULL); 61 fwrite(plane_obj, sizeof(char), strlen(plane_obj), file); 62 CHK(fclose(file) == 0); 63 64 CHK(aw_obj_load(obj, NULL) == RES_BAD_ARG); 65 CHK(aw_obj_load(NULL, "test_obj_plane.obj") == RES_BAD_ARG); 66 CHK(aw_obj_load(obj, "none.obj") == RES_IO_ERR); 67 CHK(aw_obj_load(obj, "test_obj_plane.obj") == RES_OK); 68 69 CHK(aw_obj_get_desc(NULL, NULL) == RES_BAD_ARG); 70 CHK(aw_obj_get_desc(obj, NULL) == RES_BAD_ARG); 71 CHK(aw_obj_get_desc(NULL, &desc) == RES_BAD_ARG); 72 CHK(aw_obj_get_desc(obj, &desc) == RES_OK); 73 CHK(desc.faces_count == 1); 74 CHK(desc.positions_count == 4); 75 CHK(desc.texcoords_count == 4); 76 CHK(desc.normals_count == 0); 77 CHK(desc.groups_count == 1); 78 CHK(desc.smooth_groups_count == 0); 79 CHK(desc.usemtls_count == 1); 80 CHK(desc.mtllibs_count == 1); 81 82 CHK(aw_obj_get_face(NULL, 0, &face) == RES_BAD_ARG); 83 CHK(aw_obj_get_face(obj, AW_ID_NONE, &face) == RES_BAD_ARG); 84 CHK(aw_obj_get_face(obj, 0, NULL) == RES_BAD_ARG); 85 CHK(aw_obj_get_face(obj, 0, &face) == RES_OK); 86 CHK(face.vertex_id == 0); 87 CHK(face.vertices_count == 4); 88 CHK(face.group_id == 0); 89 CHK(face.smooth_group_id == AW_ID_NONE); 90 CHK(face.mtl_id == 0); 91 92 CHK(aw_obj_get_mtl(NULL, 0, &mtl) == RES_BAD_ARG); 93 CHK(aw_obj_get_mtl(obj, AW_ID_NONE, &mtl) == RES_BAD_ARG); 94 CHK(aw_obj_get_mtl(obj, 0, NULL) == RES_BAD_ARG); 95 CHK(aw_obj_get_mtl(obj, 0, &mtl) == RES_OK); 96 CHK(!strcmp(mtl.name, "wood")); 97 CHK(mtl.face_id == 0); 98 CHK(mtl.faces_count == 1); 99 100 CHK(aw_obj_get_mtllib(NULL, 0, &mtllib) == RES_BAD_ARG); 101 CHK(aw_obj_get_mtllib(obj, AW_ID_NONE, &mtllib) == RES_BAD_ARG); 102 CHK(aw_obj_get_mtllib(obj, 0, NULL) == RES_BAD_ARG); 103 CHK(aw_obj_get_mtllib(obj, 0, &mtllib) == RES_OK); 104 CHK(strcmp(mtllib, "master.mtl") == 0); 105 106 CHK(aw_obj_get_vertex(NULL, 0, &vertex) == RES_BAD_ARG); 107 CHK(aw_obj_get_vertex(obj, AW_ID_NONE, &vertex) == RES_BAD_ARG); 108 CHK(aw_obj_get_vertex(obj, 0, NULL) == RES_BAD_ARG); 109 CHK(aw_obj_get_vertex(obj, 0, &vertex) == RES_OK); 110 111 CHK(aw_obj_get_vertex_data(NULL, &vertex, &vdata) == RES_BAD_ARG); 112 CHK(aw_obj_get_vertex_data(obj, NULL, &vdata) == RES_BAD_ARG); 113 CHK(aw_obj_get_vertex_data(obj, &vertex, NULL) == RES_BAD_ARG); 114 115 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 116 CHK(d4_eq(vdata.position, d4(v4, 0, 2, 0, 1))); 117 CHK(d3_eq(vdata.texcoord, d3(v4, 0, 1, 0))); 118 119 vertex.position_id = 4; 120 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_BAD_ARG); 121 vertex.position_id = 0; 122 vertex.texcoord_id = 4; 123 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_BAD_ARG); 124 vertex.texcoord_id = 0; 125 vertex.normal_id = 0; 126 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_BAD_ARG); 127 128 CHK(aw_obj_get_vertex(obj, 1, &vertex) == RES_OK); 129 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 130 CHK(d4_eq(vdata.position, d4(v4, 0, 0, 0, 1))); 131 CHK(d3_eq(vdata.texcoord, d3(v4, 0, 0, 0))); 132 133 CHK(aw_obj_get_vertex(obj, 2, &vertex) == RES_OK); 134 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 135 CHK(d4_eq(vdata.position, d4(v4, 2, 0, 0, 1))); 136 CHK(d3_eq(vdata.texcoord, d3(v4, 1, 0, 0))); 137 138 CHK(aw_obj_get_vertex(obj, 3, &vertex) == RES_OK); 139 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 140 CHK(d4_eq(vdata.position, d4(v4, 2, 2, 0, 1))); 141 CHK(d3_eq(vdata.texcoord, d3(v4, 1, 1, 0))); 142 143 CHK(aw_obj_get_group(NULL, 0, &group) == RES_BAD_ARG); 144 CHK(aw_obj_get_group(obj, AW_ID_NONE, &group) == RES_BAD_ARG); 145 CHK(aw_obj_get_group(obj, 0, NULL) == RES_BAD_ARG); 146 CHK(aw_obj_get_group(obj, 0, &group) == RES_OK); 147 CHK(!strcmp(group.name, "default")); 148 CHK(group.face_id == 0); 149 CHK(group.faces_count == 1); 150 151 CHK(aw_obj_get_positions(NULL, &data) == RES_BAD_ARG); 152 CHK(aw_obj_get_positions(obj, NULL) == RES_BAD_ARG); 153 CHK(aw_obj_get_positions(obj, &data) == RES_OK); 154 CHK(d4_eq(data+0, d4(v4,0,2,0,1))); 155 CHK(d4_eq(data+4, d4(v4,0,0,0,1))); 156 CHK(d4_eq(data+8, d4(v4,2,0,0,1))); 157 CHK(d4_eq(data+12, d4(v4,2,2,0,1))); 158 159 CHK(aw_obj_get_texcoords(NULL, &data) == RES_BAD_ARG); 160 CHK(aw_obj_get_texcoords(obj, NULL) == RES_BAD_ARG); 161 CHK(aw_obj_get_texcoords(obj, &data) == RES_OK); 162 CHK(d3_eq(data+0, d3(v4,0,1,0))); 163 CHK(d3_eq(data+3, d3(v4,0,0,0))); 164 CHK(d3_eq(data+6, d3(v4,1,0,0))); 165 CHK(d3_eq(data+9, d3(v4,1,1,0))); 166 } 167 168 static void 169 test_squares(struct aw_obj* obj) 170 { 171 static const char* squares_obj = 172 "v 0.000000 2.000000 0.000000\n" 173 "v 0.000000 0.000000 0.000000\n" 174 "v 2.000000 0.000000 0.000000\n" 175 "v 2.000000 2.000000 0.000000\n" 176 "v 4.000000 0.000000 -1.255298\n" 177 "v 4.000000 2.000000 -1.255298\n" 178 "vn 0.000000 0.000000 1.000000\n" 179 "vn 0.000000 0.000000 1.000000\n" 180 "vn 0.276597 0.000000 0.960986\n" 181 "vn 0.276597 0.000000 0.960986\n" 182 "vn 0.531611 0.000000 0.846988\n" 183 "vn 0.531611 0.000000 0.846988\n" 184 "# 6 vertices\n" 185 "\n" 186 "# 6 normals\n" 187 "\n" 188 "g all\n" 189 "s 1\n" 190 "f 1//1 2//2 3//3 4//4\n" 191 "f 4//4 3//3 5//5 6//6\n" 192 "# 2 elements\n"; 193 double v4[4]; 194 struct aw_obj_desc desc; 195 struct aw_obj_face face; 196 struct aw_obj_named_group group; 197 struct aw_obj_named_group mtl; 198 struct aw_obj_smooth_group sgroup; 199 struct aw_obj_vertex vertex; 200 struct aw_obj_vertex_data vdata; 201 const double* data = NULL; 202 FILE* file; 203 204 CHK(obj != NULL); 205 206 file = fopen("test_obj_squares.obj", "w"); 207 CHK(file != NULL); 208 fwrite(squares_obj, sizeof(char), strlen(squares_obj), file); 209 CHK(fclose(file) == 0); 210 CHK(aw_obj_load(obj, "test_obj_squares.obj") == RES_OK); 211 212 CHK(aw_obj_get_desc(obj, &desc) == RES_OK); 213 CHK(desc.faces_count == 2); 214 CHK(desc.positions_count == 6); 215 CHK(desc.texcoords_count == 0); 216 CHK(desc.normals_count == 6); 217 CHK(desc.groups_count == 1); 218 CHK(desc.smooth_groups_count == 1); 219 CHK(desc.usemtls_count == 0); 220 CHK(desc.mtllibs_count == 0); 221 222 CHK(aw_obj_get_face(obj, 0, &face) == RES_OK); 223 CHK(face.vertex_id == 0); 224 CHK(face.vertices_count == 4); 225 CHK(face.group_id == 0); 226 CHK(face.smooth_group_id == 0); 227 CHK(face.mtl_id == AW_ID_NONE); 228 229 CHK(aw_obj_get_vertex(obj, 0, &vertex) == RES_OK); 230 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 231 CHK(d4_eq(vdata.position, d4(v4, 0.0, 2.0, 0.0, 1.0))); 232 CHK(d3_eq(vdata.normal, d3(v4, 0.0, 0.0, 1.0))); 233 CHK(aw_obj_get_vertex(obj, 1, &vertex) == RES_OK); 234 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 235 CHK(d4_eq(vdata.position, d4(v4, 0.0, 0.0, 0.0, 1.0))); 236 CHK(d3_eq(vdata.normal, d3(v4, 0.0, 0.0, 1.0))); 237 CHK(aw_obj_get_vertex(obj, 2, &vertex) == RES_OK); 238 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 239 CHK(d4_eq(vdata.position, d4(v4, 2.0, 0.0, 0.0, 1.0))); 240 CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986))); 241 CHK(aw_obj_get_vertex(obj, 3, &vertex) == RES_OK); 242 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 243 CHK(d4_eq(vdata.position, d4(v4, 2.0, 2.0, 0.0, 1.0))); 244 CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986))); 245 246 CHK(aw_obj_get_face(obj, 1, &face) == RES_OK); 247 CHK(face.vertex_id == 4); 248 CHK(face.vertices_count == 4); 249 CHK(face.group_id == 0); 250 CHK(face.smooth_group_id == 0); 251 CHK(face.mtl_id == AW_ID_NONE); 252 253 CHK(aw_obj_get_vertex(obj, 4, &vertex) == RES_OK); 254 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 255 CHK(d4_eq(vdata.position, d4(v4, 2.0, 2.0, 0.0, 1.0))); 256 CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986))); 257 CHK(aw_obj_get_vertex(obj, 5, &vertex) == RES_OK); 258 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 259 CHK(d4_eq(vdata.position, d4(v4, 2.0, 0.0, 0.0, 1.0))); 260 CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986))); 261 CHK(aw_obj_get_vertex(obj, 6, &vertex) == RES_OK); 262 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 263 CHK(d4_eq(vdata.position, d4(v4, 4.0, 0.0, -1.255298, 1.0))); 264 CHK(d3_eq(vdata.normal, d3(v4, 0.531611, 0.0, 0.8469880))); 265 CHK(aw_obj_get_vertex(obj, 7, &vertex) == RES_OK); 266 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 267 CHK(d4_eq(vdata.position, d4(v4, 4.0, 2.0, -1.255298, 1.0)) == 1); 268 CHK(d3_eq(vdata.normal, d3(v4, 0.531611, 0.0, 0.846988)) == 1); 269 270 CHK(aw_obj_get_group(NULL, 0, &group) == RES_BAD_ARG); 271 CHK(aw_obj_get_group(obj, AW_ID_NONE, &group) == RES_BAD_ARG); 272 CHK(aw_obj_get_group(obj, 0, NULL) == RES_BAD_ARG); 273 CHK(aw_obj_get_group(obj, 0, &group) == RES_OK); 274 CHK(strcmp(group.name, "all") == 0); 275 CHK(group.face_id == 0); 276 CHK(group.faces_count == 2); 277 278 CHK(aw_obj_get_smooth_group(NULL, 0, &sgroup) == RES_BAD_ARG); 279 CHK(aw_obj_get_smooth_group(obj, AW_ID_NONE, &sgroup) == RES_BAD_ARG); 280 CHK(aw_obj_get_smooth_group(obj, 0, NULL) == RES_BAD_ARG); 281 CHK(aw_obj_get_smooth_group(obj, 0, &sgroup) == RES_OK); 282 CHK(sgroup.is_smoothed == 1); 283 CHK(sgroup.face_id == 0); 284 CHK(sgroup.faces_count == 2); 285 286 CHK(aw_obj_get_mtl(obj, 0, &mtl) == RES_BAD_ARG); 287 288 CHK(aw_obj_get_positions(obj, &data) == RES_OK); 289 CHK(d4_eq(data+0, d4(v4,0,2,0,1))); 290 CHK(d4_eq(data+4, d4(v4,0,0,0,1))); 291 CHK(d4_eq(data+8, d4(v4,2,0,0,1))); 292 CHK(d4_eq(data+12, d4(v4,2,2,0,1))); 293 CHK(d4_eq(data+16, d4(v4,4,0,-1.255298,1))); 294 CHK(d4_eq(data+20, d4(v4,4,2,-1.255298,1))); 295 296 CHK(aw_obj_get_normals(NULL, &data) == RES_BAD_ARG); 297 CHK(aw_obj_get_normals(obj, NULL) == RES_BAD_ARG); 298 CHK(aw_obj_get_normals(obj, &data) == RES_OK); 299 CHK(d3_eq(data+0, d3(v4,0,0,1))); 300 CHK(d3_eq(data+3, d3(v4,0,0,1))); 301 CHK(d3_eq(data+6, d3(v4,0.276597,0,0.960986))); 302 CHK(d3_eq(data+9, d3(v4,0.276597,0,0.960986))); 303 CHK(d3_eq(data+12, d3(v4,0.531611,0,0.846988))); 304 CHK(d3_eq(data+15, d3(v4,0.531611,0,0.846988))); 305 } 306 307 static void 308 test_cube(struct aw_obj* obj) 309 { 310 static const char* cube_obj = 311 "# Cube with a different material applied to each of its faces\n" 312 "mtllib master.mtl hop.mtl\n" 313 "mtllib my.mtl\n" 314 "v\t0.0000 2.0000 2.0000\n" 315 "v 0.0000 0.0000 2.0000\n" 316 "v 2.0000 0.0000 2.0000\n" 317 "v 2.0000 2.0000 2.0000\n" 318 "v 0.0000 2.0000 0.0000\n" 319 "v 0.0000 0.0000 0.0000\n" 320 "v 2.0000 0.0000 0.0000\n" 321 "v 2.0000 2.0000 0.0000\n" 322 "# 8 vertices\n" 323 "g front\n" 324 "usemtl red\n" 325 "f 1\t\t\t 2 3 4\n" 326 "g back\n" 327 "usemtl blue\n" 328 "f 8 7 6 5\n" 329 "g right\n" 330 "usemtl green\n" 331 "f 4 3 7 8\n" 332 "g top\n" 333 "usemtl\tgold\n" 334 "f 5 1\t4 8\n" 335 "g left\n" 336 "usemtl orange\n" 337 "f 5 6 2 1\n" 338 "g bottom\n" 339 "usemtl purple\n" 340 "f 2 6 7 3\n" 341 "# 6 elements\n"; 342 double v4[4]; 343 const char* group_names[6] = 344 { "front", "back", "right", "top", "left", "bottom" }; 345 const char* mtl_names[6] = 346 { "red", "blue", "green", "gold", "orange", "purple" }; 347 struct aw_obj_desc desc; 348 FILE* file; 349 const char* mtllib; 350 const double* data; 351 size_t i; 352 353 CHK(obj != NULL); 354 355 file = fopen("test_obj_cube.obj", "w+"); 356 CHK(file != NULL); 357 fwrite(cube_obj, sizeof(char), strlen(cube_obj), file); 358 CHK(fseek(file, 0, SEEK_SET) == 0); 359 360 CHK(aw_obj_load_stream(obj, NULL, NULL) == RES_BAD_ARG); 361 CHK(aw_obj_load_stream(NULL, file, NULL) == RES_BAD_ARG); 362 CHK(aw_obj_load_stream(obj, file, NULL) == RES_OK); 363 364 CHK(aw_obj_get_desc(obj, &desc) == RES_OK); 365 CHK(desc.faces_count == 6); 366 CHK(desc.positions_count == 8); 367 CHK(desc.texcoords_count == 0); 368 CHK(desc.normals_count == 0); 369 CHK(desc.groups_count == 6); 370 CHK(desc.smooth_groups_count == 0); 371 CHK(desc.usemtls_count == 6); 372 CHK(desc.mtllibs_count == 3); 373 374 CHK(aw_obj_clear(NULL) == RES_BAD_ARG); 375 CHK(aw_obj_clear(obj) == RES_OK); 376 CHK(aw_obj_get_desc(obj, &desc) == RES_OK); 377 CHK(desc.faces_count == 0); 378 CHK(desc.groups_count == 0); 379 CHK(desc.smooth_groups_count == 0); 380 CHK(desc.usemtls_count == 0); 381 CHK(desc.mtllibs_count == 0); 382 383 CHK(fseek(file, 0, SEEK_SET) == 0); 384 CHK(aw_obj_load_stream(obj, file, "cube") == RES_OK); 385 CHK(aw_obj_get_desc(obj, &desc) == RES_OK); 386 387 FOR_EACH(i, 0, 6) { 388 struct aw_obj_face face; 389 CHK(aw_obj_get_face(obj, i, &face) == RES_OK); 390 CHK(face.vertex_id == i*4); 391 CHK(face.vertices_count == 4); 392 CHK(face.group_id == i); 393 CHK(face.smooth_group_id == AW_ID_NONE); 394 CHK(face.mtl_id == i); 395 } 396 397 FOR_EACH(i, 0, 6) { 398 struct aw_obj_named_group group; 399 CHK(aw_obj_get_group(obj, i, &group) == RES_OK); 400 CHK(!strcmp(group.name, group_names[i])); 401 CHK(group.face_id == i); 402 CHK(group.faces_count == 1); 403 } 404 405 FOR_EACH(i, 0, 6) { 406 struct aw_obj_named_group mtl; 407 CHK(aw_obj_get_mtl(obj, i, &mtl) == RES_OK); 408 CHK(!strcmp(mtl.name, mtl_names[i])); 409 CHK(mtl.face_id == i); 410 CHK(mtl.faces_count == 1); 411 } 412 413 CHK(aw_obj_get_mtllib(obj, 0, &mtllib) == RES_OK); 414 CHK(!strcmp(mtllib, "master.mtl")); 415 CHK(aw_obj_get_mtllib(obj, 1, &mtllib) == RES_OK); 416 CHK(!strcmp(mtllib, "hop.mtl")); 417 CHK(aw_obj_get_mtllib(obj, 2, &mtllib) == RES_OK); 418 CHK(!strcmp(mtllib, "my.mtl")); 419 CHK(aw_obj_get_mtllib(obj, 3, &mtllib) == RES_BAD_ARG); 420 421 CHK(aw_obj_get_positions(obj, &data) == RES_OK); 422 CHK(d4_eq(data+0, d4(v4,0,2,2,1))); 423 CHK(d4_eq(data+4, d4(v4,0,0,2,1))); 424 CHK(d4_eq(data+8, d4(v4,2,0,2,1))); 425 CHK(d4_eq(data+12, d4(v4,2,2,2,1))); 426 CHK(d4_eq(data+16, d4(v4,0,2,0,1))); 427 CHK(d4_eq(data+20, d4(v4,0,0,0,1))); 428 CHK(d4_eq(data+24, d4(v4,2,0,0,1))); 429 CHK(d4_eq(data+28, d4(v4,2,2,0,1))); 430 431 CHK(aw_obj_purge(NULL) == RES_BAD_ARG); 432 CHK(aw_obj_purge(obj) == RES_OK); 433 CHK(aw_obj_get_desc(obj, &desc) == RES_OK); 434 CHK(desc.faces_count == 0); 435 CHK(desc.groups_count == 0); 436 CHK(desc.smooth_groups_count == 0); 437 CHK(desc.usemtls_count == 0); 438 CHK(desc.mtllibs_count == 0); 439 440 CHK(fclose(file) == 0); 441 } 442 443 static void 444 test_cbox(struct aw_obj* obj) 445 { 446 static const char* cbox_obj = 447 "mtllib cbox.mtl\n" 448 "v -1.01 0 0.99\n" 449 "v 1 0 0.99\n" 450 "v 1 0 -1.04\n" 451 "v -0.99 0 -1.04\n" 452 "g floor\n" 453 "usemtl floor\n" 454 "f -4 -3 -2 -1\n" 455 456 "v -1.02 1.99 0.99\n" 457 "v -1.02 1.99 -1.04\n" 458 "v 1 1.99 -1.04\n" 459 "v 1 1.99 0.99\n" 460 "g ceiling\n" 461 "usemtl ceiling\n" 462 "f -4 -3 -2 -1\n" 463 464 "v -0.99 0 -1.04\n" 465 "v 1 0 -1.04\n" 466 "v 1 1.99 -1.04\n" 467 "v -1.02 1.99 -1.04\n" 468 "g back\n" 469 "usemtl back\n" 470 "f -4 -3 -2 -1\n" 471 472 "v 1 0 -1.04\n" 473 "v 1 0 0.99\n" 474 "v 1 1.99 0.99\n" 475 "v 1 1.99 -1.04\n" 476 "g right\n" 477 "usemtl right\n" 478 "f -4 -3 -2 -1\n" 479 480 "v -1.01 0 0.99\n" 481 "v -0.99 0 -1.04\n" 482 "v -1.02 1.99 -1.04\n" 483 "v -1.02 1.99 0.99\n" 484 "g left\n" 485 "usemtl left\n" 486 "f -4 -3 -2 -1"; 487 struct aw_obj_desc desc; 488 struct aw_obj_face face; 489 struct aw_obj_vertex vertex; 490 struct aw_obj_vertex_data vdata; 491 struct aw_obj_named_group group; 492 struct aw_obj_named_group mtl; 493 double v4[4]; 494 double tmp[3]; 495 const double* data; 496 FILE* file; 497 498 CHK(obj != NULL); 499 500 file = fopen("test_cbox.obj", "w+"); 501 CHK(file != NULL); 502 fwrite(cbox_obj, sizeof(char), strlen(cbox_obj), file); 503 CHK(fseek(file, 0, SEEK_SET) == 0); 504 CHK(aw_obj_load_stream(obj, file, "cbox") == RES_OK); 505 CHK(fclose(file) == 0); 506 507 CHK(aw_obj_get_desc(obj, &desc) == RES_OK); 508 CHK(desc.faces_count == 5); 509 CHK(desc.positions_count == 20); 510 CHK(desc.texcoords_count == 0); 511 CHK(desc.normals_count == 0); 512 CHK(desc.groups_count == 5); 513 CHK(desc.smooth_groups_count == 0); 514 CHK(desc.usemtls_count == 5); 515 CHK(desc.mtllibs_count == 1); 516 517 CHK(aw_obj_get_face(obj, 0, &face) == RES_OK); 518 CHK(face.vertex_id == 0); 519 CHK(face.vertices_count == 4); 520 CHK(face.group_id == 0); 521 CHK(face.mtl_id == 0); 522 523 CHK(aw_obj_get_group(obj, 0, &group) == RES_OK); 524 CHK(!strcmp(group.name, "floor")); 525 CHK(group.face_id == 0); 526 CHK(group.faces_count == 1); 527 528 CHK(aw_obj_get_mtl(obj, 0, &mtl) == RES_OK); 529 CHK(!strcmp(mtl.name, "floor")); 530 CHK(mtl.face_id == 0); 531 CHK(mtl.faces_count == 1); 532 533 CHK(aw_obj_get_vertex(obj, 0, &vertex) == RES_OK); 534 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 535 CHK(d3_eq_eps(vdata.position, d3(tmp, -1.01, 0.0, 0.99), 1.e-6)); 536 CHK(aw_obj_get_vertex(obj, 1, &vertex) == RES_OK); 537 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 538 CHK(d3_eq_eps(vdata.position, d3(tmp, 1.0, 0.0, 0.99), 1.e-6)); 539 CHK(aw_obj_get_vertex(obj, 2, &vertex) == RES_OK); 540 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 541 CHK(d3_eq_eps(vdata.position, d3(tmp, 1.f, 0.0, -1.04), 1.e-6)); 542 CHK(aw_obj_get_vertex(obj, 3, &vertex) == RES_OK); 543 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 544 CHK(d3_eq_eps(vdata.position, d3(tmp, -0.99, 0.0, -1.04), 1.e-6)); 545 546 CHK(aw_obj_get_face(obj, 1, &face) == RES_OK); 547 CHK(face.vertex_id == 4); 548 CHK(face.vertices_count == 4); 549 CHK(face.group_id == 1); 550 CHK(face.mtl_id == 1); 551 552 CHK(aw_obj_get_group(obj, 1, &group) == RES_OK); 553 CHK(!strcmp(group.name, "ceiling")); 554 CHK(group.face_id == 1); 555 CHK(group.faces_count == 1); 556 557 CHK(aw_obj_get_mtl(obj, 1, &mtl) == RES_OK); 558 CHK(!strcmp(mtl.name, "ceiling")); 559 CHK(mtl.face_id == 1); 560 CHK(mtl.faces_count == 1); 561 562 CHK(aw_obj_get_vertex(obj, 4, &vertex) == RES_OK); 563 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 564 CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, 0.99), 1.e-6)); 565 CHK(aw_obj_get_vertex(obj, 5, &vertex) == RES_OK); 566 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 567 CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, -1.04), 1.e-6f)); 568 CHK(aw_obj_get_vertex(obj, 6, &vertex) == RES_OK); 569 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 570 CHK(d3_eq_eps(vdata.position, d3(tmp, 1.0, 1.99, -1.04), 1.e-6f)); 571 CHK(aw_obj_get_vertex(obj, 7, &vertex) == RES_OK); 572 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 573 CHK(d3_eq_eps(vdata.position, d3(tmp, 1.0, 1.99, 0.99), 1.e-6f)); 574 575 CHK(aw_obj_get_face(obj, 4, &face) == RES_OK); 576 CHK(face.vertex_id == 16); 577 CHK(face.vertices_count == 4); 578 CHK(face.group_id == 4); 579 CHK(face.mtl_id == 4); 580 581 CHK(aw_obj_get_group(obj, 4, &group) == RES_OK); 582 CHK(!strcmp(group.name, "left")); 583 CHK(group.face_id == 4); 584 CHK(group.faces_count == 1); 585 586 CHK(aw_obj_get_mtl(obj, 4, &mtl) == RES_OK); 587 CHK(!strcmp(mtl.name, "left")); 588 CHK(mtl.face_id == 4); 589 CHK(mtl.faces_count == 1); 590 591 CHK(aw_obj_get_vertex(obj, 16, &vertex) == RES_OK); 592 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 593 CHK(d3_eq_eps(vdata.position, d3(tmp, -1.01, 0.0, 0.99), 1.e-6)); 594 CHK(aw_obj_get_vertex(obj, 17, &vertex) == RES_OK); 595 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 596 CHK(d3_eq_eps(vdata.position, d3(tmp, -0.99, 0.0, -1.04), 1.e-6)); 597 CHK(aw_obj_get_vertex(obj, 18, &vertex) == RES_OK); 598 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 599 CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, -1.04), 1.e-6)); 600 CHK(aw_obj_get_vertex(obj, 19, &vertex) == RES_OK); 601 CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK); 602 CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, 0.99), 1.e-6)); 603 604 CHK(aw_obj_get_positions(obj, &data) == RES_OK); 605 CHK(d4_eq(data+0, d4(v4,-1.01,0,0.99,1))); 606 CHK(d4_eq(data+4, d4(v4,1,0,0.99,1))); 607 CHK(d4_eq(data+8, d4(v4,1,0,-1.04,1))); 608 CHK(d4_eq(data+12, d4(v4,-0.99,0,-1.04,1))); 609 CHK(d4_eq(data+16, d4(v4,-1.02,1.99,0.99,1))); 610 CHK(d4_eq(data+20, d4(v4,-1.02,1.99,-1.04,1))); 611 CHK(d4_eq(data+24, d4(v4,1,1.99,-1.04,1))); 612 CHK(d4_eq(data+28, d4(v4,1,1.99,0.99,1))); 613 CHK(d4_eq(data+32, d4(v4,-0.99,0,-1.04,1))); 614 CHK(d4_eq(data+36, d4(v4,1,0,-1.04,1))); 615 CHK(d4_eq(data+40, d4(v4,1,1.99,-1.04,1))); 616 CHK(d4_eq(data+44, d4(v4,-1.02,1.99,-1.04,1))); 617 CHK(d4_eq(data+48, d4(v4,1,0,-1.04,1))); 618 CHK(d4_eq(data+52, d4(v4,1,0,0.99,1))); 619 CHK(d4_eq(data+56, d4(v4,1,1.99,0.99,1))); 620 CHK(d4_eq(data+60, d4(v4,1,1.99,-1.04,1))); 621 CHK(d4_eq(data+64, d4(v4,-1.01,0,0.99,1))); 622 CHK(d4_eq(data+68, d4(v4,-0.99,0,-1.04,1))); 623 CHK(d4_eq(data+72, d4(v4,-1.02,1.99,-1.04,1))); 624 CHK(d4_eq(data+76, d4(v4,-1.02,1.99,0.99,1))); 625 } 626 627 int 628 main(int argc, char** argv) 629 { 630 struct mem_allocator allocator; 631 struct aw_obj* obj; 632 int i; 633 634 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 635 636 CHK(aw_obj_create(LOGGER_DEFAULT, NULL, 1, NULL) == RES_BAD_ARG); 637 CHK(aw_obj_create(LOGGER_DEFAULT, &allocator, 1, NULL) == RES_BAD_ARG); 638 CHK(aw_obj_create(LOGGER_DEFAULT, NULL, 1, &obj) == RES_OK); 639 640 CHK(aw_obj_ref_get(NULL) == RES_BAD_ARG); 641 CHK(aw_obj_ref_get(obj) == RES_OK); 642 CHK(aw_obj_ref_put(NULL) == RES_BAD_ARG); 643 CHK(aw_obj_ref_put(obj) == RES_OK); 644 CHK(aw_obj_ref_put(obj) == RES_OK); 645 646 CHK(aw_obj_create(NULL, &allocator, 1, &obj) == RES_OK); 647 648 test_plane(obj); 649 test_squares(obj); 650 test_cube(obj); 651 test_cbox(obj); 652 FOR_EACH(i, 1, argc) 653 CHK(aw_obj_load(obj, argv[i]) == RES_OK); 654 655 CHK(aw_obj_ref_put(obj) == RES_OK); 656 657 if(MEM_ALLOCATED_SIZE(&allocator)) { 658 char dump[512]; 659 MEM_DUMP(&allocator, dump, sizeof(dump)/sizeof(char)); 660 fprintf(stderr, "%s\n", dump); 661 FATAL("Memory leaks\n"); 662 } 663 mem_shutdown_proxy_allocator(&allocator); 664 CHK(mem_allocated_size() == 0); 665 return 0; 666 } 667