loader_aw

Load OBJ/MTL file formats
git clone git://git.meso-star.fr/loader_aw.git
Log | Files | Refs | README | LICENSE

commit 839c8f2b8a70fd67e2b2c166218a58a4288a1c76
parent bad0c766c1e7796a434d6b365b01bae54426cf52
Author: vaplv <vaplv@free.fr>
Date:   Wed,  7 Jan 2015 11:37:06 +0100

Change the API of the obj named group data structure

Diffstat:
Mcmake/CMakeLists.txt | 6+++---
Msrc/aw.h | 36++++++++++++++++++++++++++----------
Msrc/aw_obj.c | 140+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/test_aw_obj.c | 60+++++++++++++++++++++++++++++++++++++++++-------------------
4 files changed, 139 insertions(+), 103 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2014 Vincent Forest (vaplv@free.fr) +# Copyright (C) 2013-2015 Vincent Forest (vaplv@free.fr) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -41,8 +41,8 @@ rcmake_prepend_path(AW_FILES_INC ${AW_SOURCE_DIR}) add_library(aw SHARED ${AW_FILES_SRC} ${AW_FILES_INC}) target_link_libraries(aw RSys) -set(VERSION_MAJOR 0) -set(VERSION_MINOR 1) +set(VERSION_MAJOR 1) +set(VERSION_MINOR 0) set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set_target_properties(aw PROPERTIES diff --git a/src/aw.h b/src/aw.h @@ -72,8 +72,8 @@ struct aw_obj_face { size_t mtl_id; /* Index of the face material */ }; -struct aw_obj_group { - const char* name; +struct aw_obj_named_group { + struct str name; size_t face_id; /* Index of the first group face */ size_t faces_count; }; @@ -84,12 +84,6 @@ struct aw_obj_smooth_group { size_t faces_count; }; -struct aw_obj_mtl { - const char* name; - size_t face_id; - size_t faces_count; -}; - struct aw_obj_vertex { float position[4]; float normal[3]; @@ -183,7 +177,7 @@ AW_API res_T aw_obj_group_get (const struct aw_obj* obj, const size_t group_id, - struct aw_obj_group* group); + struct aw_obj_named_group* group); AW_API res_T aw_obj_smooth_group_get @@ -195,7 +189,7 @@ AW_API res_T aw_obj_mtl_get (const struct aw_obj* obj, const size_t mtl_id, - struct aw_obj_mtl* mtl); + struct aw_obj_named_group* mtl); AW_API res_T aw_obj_mtllib_get @@ -253,6 +247,28 @@ aw_mtl_material_get struct aw_material* material); /******************************************************************************* + * Obj group functions + ******************************************************************************/ +AW_API res_T +aw_obj_named_group_init + (struct mem_allocator* allocator, + struct aw_obj_named_group* grp); + +AW_API res_T +aw_obj_named_group_release + (struct aw_obj_named_group* grp); + +AW_API res_T +aw_obj_named_group_copy + (struct aw_obj_named_group* dst, + const struct aw_obj_named_group* src); + +AW_API res_T +aw_obj_named_group_copy_and_release + (struct aw_obj_named_group* dst, + struct aw_obj_named_group* src); + +/******************************************************************************* * Map functions ******************************************************************************/ AW_API res_T diff --git a/src/aw_obj.c b/src/aw_obj.c @@ -36,46 +36,6 @@ struct vertex { }; static const struct vertex VERTEX_NULL = { AW_ID_NONE, AW_ID_NONE, AW_ID_NONE }; -struct named_group { - struct str name; - size_t iface; /* Index toward the first face */ - size_t nfaces; /* Faces count in the group */ -}; - -static INLINE void -named_group_init(struct mem_allocator* allocator, struct named_group* grp) -{ - ASSERT(grp); - str_init(allocator, &grp->name); - grp->iface = 0; - grp->nfaces = 0; -} - -static INLINE void -named_group_release(struct named_group* grp) -{ - ASSERT(grp); - str_release(&grp->name); -} - -static INLINE res_T -named_group_copy(struct named_group* dst, const struct named_group* src) -{ - ASSERT(dst && src); - dst->iface = src->iface; - dst->nfaces = src->nfaces; - return str_copy(&dst->name, &src->name); -} - -static INLINE res_T -named_group_copy_and_release(struct named_group* dst, struct named_group* src) -{ - ASSERT(dst && src); - dst->iface = src->iface; - dst->nfaces = src->nfaces; - return str_copy_and_release(&dst->name, &src->name); -} - /* Generate the darray_vertex data structure */ #define DARRAY_NAME vertex #define DARRAY_DATA struct vertex @@ -88,11 +48,11 @@ named_group_copy_and_release(struct named_group* dst, struct named_group* src) /* Generate the darray_named_group data structure */ #define DARRAY_NAME named_group -#define DARRAY_DATA struct named_group -#define DARRAY_FUNCTOR_INIT named_group_init -#define DARRAY_FUNCTOR_RELEASE named_group_release -#define DARRAY_FUNCTOR_COPY named_group_copy -#define DARRAY_FUNCTOR_COPY_AND_RELEASE named_group_copy_and_release +#define DARRAY_DATA struct aw_obj_named_group +#define DARRAY_FUNCTOR_INIT aw_obj_named_group_init +#define DARRAY_FUNCTOR_RELEASE aw_obj_named_group_release +#define DARRAY_FUNCTOR_COPY aw_obj_named_group_copy +#define DARRAY_FUNCTOR_COPY_AND_RELEASE aw_obj_named_group_copy_and_release #include <rsys/dynamic_array.h> /* Generate the darray_smooth_group data structure */ @@ -145,17 +105,17 @@ flush_groups(struct aw_obj* obj) if(obj->igroups_active >= ngrps) return; FOR_EACH(obj->igroups_active, obj->igroups_active, ngrps) { - struct named_group* grp; + struct aw_obj_named_group* grp; grp = darray_named_group_data_get(&obj->groups) + obj->igroups_active; - ASSERT(grp->iface <= nfaces); - grp->nfaces = nfaces - grp->iface; + ASSERT(grp->face_id <= nfaces); + grp->faces_count = nfaces - grp->face_id; } } static FINLINE void flush_usemtl(struct aw_obj* obj) { - struct named_group* mtl; + struct aw_obj_named_group* mtl; size_t nfaces, ngrps; ASSERT(obj); if(0 == (nfaces = darray_face_size_get(&obj->faces))) @@ -163,8 +123,8 @@ flush_usemtl(struct aw_obj* obj) if(0 == (ngrps = darray_named_group_size_get(&obj->usemtls))) return; mtl = darray_named_group_data_get(&obj->usemtls) + (ngrps - 1); - ASSERT(mtl->iface <= nfaces); - mtl->nfaces = nfaces - mtl->iface; + ASSERT(mtl->face_id <= nfaces); + mtl->faces_count = nfaces - mtl->face_id; } static FINLINE void @@ -303,7 +263,7 @@ parse_group(struct aw_obj* obj, char** word_tk) ngrps = igrp = darray_named_group_size_get(&obj->groups); obj->igroups_active = ngrps; do { - struct named_group* grp = NULL; + struct aw_obj_named_group* grp = NULL; res = darray_named_group_resize(&obj->groups, igrp + 1); if(res != RES_OK) goto error; @@ -312,8 +272,8 @@ parse_group(struct aw_obj* obj, char** word_tk) res = str_set(&grp->name, word ? word : "default"); if(res != RES_OK) goto error; - grp->iface = darray_face_size_get(&obj->faces); - grp->nfaces = 0; + grp->face_id = darray_face_size_get(&obj->faces); + grp->faces_count = 0; } while((word = strtok_r(NULL, " \t", word_tk))); exit: @@ -395,7 +355,7 @@ static res_T parse_usemtl(struct aw_obj* obj, char** word_tk) { char* word; - struct named_group* mtl = NULL; + struct aw_obj_named_group* mtl = NULL; size_t nmtls; res_T res = RES_OK; ASSERT(obj && word_tk); @@ -416,8 +376,8 @@ parse_usemtl(struct aw_obj* obj, char** word_tk) res = str_set(&mtl->name, word); if(res != RES_OK) goto error; - mtl->iface = darray_face_size_get(&obj->faces); - mtl->nfaces = 0; + mtl->face_id = darray_face_size_get(&obj->faces); + mtl->faces_count = 0; exit: return res; @@ -679,16 +639,15 @@ aw_obj_face_get res_T aw_obj_group_get - (const struct aw_obj* obj, const size_t igroup, struct aw_obj_group* grp) + (const struct aw_obj* obj, + const size_t igroup, + struct aw_obj_named_group* grp) { - const struct named_group* group; + const struct aw_obj_named_group* src; if(!obj || !grp || igroup >= darray_named_group_size_get(&obj->groups)) return RES_BAD_ARG; - group = darray_named_group_cdata_get(&obj->groups) + igroup; - grp->name = str_cget(&group->name); - grp->face_id = group->iface; - grp->faces_count = group->nfaces; - return RES_OK; + src = darray_named_group_cdata_get(&obj->groups) + igroup; + return aw_obj_named_group_copy(grp, src); } res_T @@ -706,16 +665,15 @@ aw_obj_smooth_group_get res_T aw_obj_mtl_get - (const struct aw_obj* obj, const size_t imtl, struct aw_obj_mtl* mtl) + (const struct aw_obj* obj, + const size_t imtl, + struct aw_obj_named_group* mtl) { - const struct named_group* group; + const struct aw_obj_named_group* src; if(!obj || !mtl || imtl >= darray_named_group_size_get(&obj->usemtls)) return RES_BAD_ARG; - group = darray_named_group_cdata_get(&obj->usemtls) + imtl; - mtl->name = str_cget(&group->name); - mtl->face_id = group->iface; - mtl->faces_count = group->nfaces; - return RES_OK; + src = darray_named_group_cdata_get(&obj->usemtls) + imtl; + return aw_obj_named_group_copy(mtl, src); } res_T @@ -761,3 +719,43 @@ aw_obj_vertex_get return RES_OK; } +res_T +aw_obj_named_group_init + (struct mem_allocator* allocator, struct aw_obj_named_group* grp) +{ + if(!grp) return RES_BAD_ARG; + str_init(allocator, &grp->name); + return RES_OK; +} + +res_T +aw_obj_named_group_release(struct aw_obj_named_group* grp) +{ + if(!grp) return RES_BAD_ARG; + str_release(&grp->name); + return RES_OK; +} + +res_T +aw_obj_named_group_copy + (struct aw_obj_named_group* dst, + const struct aw_obj_named_group* src) +{ + if(!dst || !src) return RES_BAD_ARG; + if(dst == src) return RES_OK; + dst->face_id = src->face_id; + dst->faces_count = src->faces_count; + return str_copy(&dst->name, &src->name); +} + +res_T +aw_obj_named_group_copy_and_release + (struct aw_obj_named_group* dst, struct aw_obj_named_group* src) +{ + if(!dst || !src) return RES_BAD_ARG; + if(dst == src) return RES_OK; + dst->face_id = src->face_id; + dst->faces_count = src->faces_count; + return str_copy_and_release(&dst->name, &src->name); +} + diff --git a/src/test_aw_obj.c b/src/test_aw_obj.c @@ -45,8 +45,8 @@ test_plane(struct aw_obj* obj) float v4[4]; struct aw_obj_desc desc; struct aw_obj_face face; - struct aw_obj_group group; - struct aw_obj_mtl mtl; + struct aw_obj_named_group group; + struct aw_obj_named_group mtl; struct aw_obj_vertex vertex; FILE* file; const char* mtllib; @@ -58,6 +58,10 @@ test_plane(struct aw_obj* obj) fwrite(plane_obj, sizeof(char), strlen(plane_obj), file); fclose(file); + CHECK(aw_obj_named_group_init(NULL, NULL), RES_BAD_ARG); + CHECK(aw_obj_named_group_init(NULL, &group), RES_OK); + CHECK(aw_obj_named_group_init(NULL, &mtl), RES_OK); + CHECK(aw_obj_load(NULL, NULL), RES_BAD_ARG); CHECK(aw_obj_load(obj, NULL), RES_BAD_ARG); CHECK(aw_obj_load(NULL, "test_obj_plane.obj"), RES_BAD_ARG); @@ -96,7 +100,7 @@ test_plane(struct aw_obj* obj) CHECK(aw_obj_mtl_get(obj, AW_ID_NONE, &mtl), RES_BAD_ARG); CHECK(aw_obj_mtl_get(NULL, 0, &mtl), RES_BAD_ARG); CHECK(aw_obj_mtl_get(obj, 0, &mtl), RES_OK); - CHECK(strcmp(mtl.name, "wood"), 0); + CHECK(strcmp(str_cget(&mtl.name), "wood"), 0); CHECK(mtl.face_id, 0); CHECK(mtl.faces_count, 1); @@ -139,9 +143,13 @@ test_plane(struct aw_obj* obj) CHECK(aw_obj_group_get(obj, AW_ID_NONE, &group), RES_BAD_ARG); CHECK(aw_obj_group_get(NULL, 0, &group), RES_BAD_ARG); CHECK(aw_obj_group_get(obj, 0, &group), RES_OK); - CHECK(strcmp(group.name, "default"), 0); + CHECK(strcmp(str_cget(&group.name), "default"), 0); CHECK(group.face_id, 0); CHECK(group.faces_count, 1); + + CHECK(aw_obj_named_group_release(NULL), RES_BAD_ARG); + CHECK(aw_obj_named_group_release(&group), RES_OK); + CHECK(aw_obj_named_group_release(&mtl), RES_OK); } static void @@ -172,13 +180,15 @@ test_squares(struct aw_obj* obj) float v4[4]; struct aw_obj_desc desc; struct aw_obj_face face; - struct aw_obj_group group; + struct aw_obj_named_group group; + struct aw_obj_named_group mtl; struct aw_obj_smooth_group sgroup; - struct aw_obj_mtl mtl; struct aw_obj_vertex vertex; FILE* file; NCHECK(obj, NULL); + CHECK(aw_obj_named_group_init(NULL, &group), RES_OK); + CHECK(aw_obj_named_group_init(NULL, &mtl), RES_OK); file = fopen("test_obj_squares.obj", "w"); NCHECK(file, NULL); @@ -241,7 +251,7 @@ test_squares(struct aw_obj* obj) CHECK(aw_obj_group_get(obj, AW_ID_NONE, &group), RES_BAD_ARG); CHECK(aw_obj_group_get(NULL, 0, &group), RES_BAD_ARG); CHECK(aw_obj_group_get(obj, 0, &group), RES_OK); - CHECK(strcmp(group.name, "all"), 0); + CHECK(strcmp(str_cget(&group.name), "all"), 0); CHECK(group.face_id, 0); CHECK(group.faces_count, 2); @@ -258,6 +268,9 @@ test_squares(struct aw_obj* obj) CHECK(sgroup.faces_count, 2); CHECK(aw_obj_mtl_get(obj, 0, &mtl), RES_BAD_ARG); + + CHECK(aw_obj_named_group_release(&group), RES_OK); + CHECK(aw_obj_named_group_release(&mtl), RES_OK); } static void @@ -347,19 +360,23 @@ test_cube(struct aw_obj* obj) } FOR_EACH(i, 0, 6) { - struct aw_obj_group group; + struct aw_obj_named_group group; + CHECK(aw_obj_named_group_init(NULL, &group), RES_OK); CHECK(aw_obj_group_get(obj, i, &group), RES_OK); - CHECK(strcmp(group.name, group_names[i]), 0); + CHECK(strcmp(str_cget(&group.name), group_names[i]), 0); CHECK(group.face_id, i); CHECK(group.faces_count, 1); + CHECK(aw_obj_named_group_release(&group), RES_OK); } FOR_EACH(i, 0, 6) { - struct aw_obj_mtl mtl; + struct aw_obj_named_group mtl; + CHECK(aw_obj_named_group_init(NULL, &mtl), RES_OK); CHECK(aw_obj_mtl_get(obj, i, &mtl), RES_OK); - CHECK(strcmp(mtl.name, mtl_names[i]), 0); + CHECK(strcmp(str_cget(&mtl.name), mtl_names[i]), 0); CHECK(mtl.face_id, i); CHECK(mtl.faces_count, 1); + CHECK(aw_obj_named_group_release(&mtl), RES_OK); } CHECK(aw_obj_mtllib_get(obj, 0, &mtllib), RES_OK); @@ -420,12 +437,14 @@ test_cbox(struct aw_obj* obj) struct aw_obj_desc desc; struct aw_obj_face face; struct aw_obj_vertex vertex; - struct aw_obj_group group; - struct aw_obj_mtl mtl; + struct aw_obj_named_group group; + struct aw_obj_named_group mtl; float tmp[3]; FILE* file; NCHECK(obj, NULL); + CHECK(aw_obj_named_group_init(NULL, &group), RES_OK); + CHECK(aw_obj_named_group_init(NULL, &mtl), RES_OK); file = fopen("test_cbox.obj", "w+"); NCHECK(file, NULL); @@ -448,12 +467,12 @@ test_cbox(struct aw_obj* obj) CHECK(face.mtl_id, 0); CHECK(aw_obj_group_get(obj, 0, &group), RES_OK); - CHECK(strcmp(group.name, "floor"), 0); + CHECK(strcmp(str_cget(&group.name), "floor"), 0); CHECK(group.face_id, 0); CHECK(group.faces_count, 1); CHECK(aw_obj_mtl_get(obj, 0, &mtl), RES_OK); - CHECK(strcmp(mtl.name, "floor"), 0); + CHECK(strcmp(str_cget(&mtl.name), "floor"), 0); CHECK(mtl.face_id, 0); CHECK(mtl.faces_count, 1); @@ -473,12 +492,12 @@ test_cbox(struct aw_obj* obj) CHECK(face.mtl_id, 1); CHECK(aw_obj_group_get(obj, 1, &group), RES_OK); - CHECK(strcmp(group.name, "ceiling"), 0); + CHECK(strcmp(str_cget(&group.name), "ceiling"), 0); CHECK(group.face_id, 1); CHECK(group.faces_count, 1); CHECK(aw_obj_mtl_get(obj, 1, &mtl), RES_OK); - CHECK(strcmp(mtl.name, "ceiling"), 0); + CHECK(strcmp(str_cget(&mtl.name), "ceiling"), 0); CHECK(mtl.face_id, 1); CHECK(mtl.faces_count, 1); @@ -498,12 +517,12 @@ test_cbox(struct aw_obj* obj) CHECK(face.mtl_id, 4); CHECK(aw_obj_group_get(obj, 4, &group), RES_OK); - CHECK(strcmp(group.name, "left"), 0); + CHECK(strcmp(str_cget(&group.name), "left"), 0); CHECK(group.face_id, 4); CHECK(group.faces_count, 1); CHECK(aw_obj_mtl_get(obj, 4, &mtl), RES_OK); - CHECK(strcmp(mtl.name, "left"), 0); + CHECK(strcmp(str_cget(&mtl.name), "left"), 0); CHECK(mtl.face_id, 4); CHECK(mtl.faces_count, 1); @@ -515,6 +534,9 @@ test_cbox(struct aw_obj* obj) CHECK(f3_eq_eps(vertex.position, f3(tmp, -1.02f, 1.99f, -1.04f), 1.e-6f), 1); CHECK(aw_obj_vertex_get(obj, 19, &vertex), RES_OK); CHECK(f3_eq_eps(vertex.position, f3(tmp, -1.02f, 1.99f, 0.99f), 1.e-6f), 1); + + CHECK(aw_obj_named_group_release(&group), RES_OK); + CHECK(aw_obj_named_group_release(&mtl), RES_OK); } int