commit b7c5fb41045859eea417ae05c81cc6c36ad34711
parent 8509db08af97230749d2f0afa79560ba49860b0b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 31 Jan 2020 18:28:13 +0100
Review and clean-up the code
Update the code to handle the API updates of the aw 2.0 library.
Diffstat:
2 files changed, 115 insertions(+), 246 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -36,7 +36,7 @@ option(NO_TEST "Disable the test" OFF)
################################################################################
# Check dependencies
################################################################################
-find_package(AW 1.2.0 REQUIRED)
+find_package(AW 2.0.0 REQUIRED)
find_package(Polygon 0.1 REQUIRED)
find_package(RCMake 0.2 REQUIRED)
find_package(RSys 0.6 REQUIRED)
diff --git a/src/s3daw.c b/src/s3daw.c
@@ -30,8 +30,8 @@
#include "s3daw.h"
-#include <rsys/dynamic_array_char.h>
-#include <rsys/dynamic_array_size_t.h>
+#include <rsys/dynamic_array_uint.h>
+#include <rsys/dynamic_array_float.h>
#include <rsys/float3.h>
#include <rsys/float4.h>
#include <rsys/hash_table.h>
@@ -45,30 +45,13 @@
#include <polygon.h>
#include <string.h>
-#ifdef COMPILER_GCC
- #include <libgen.h> /* dirname function */
-#endif
-
#define DARRAY_NAME shape
#define DARRAY_DATA struct s3d_shape*
#include <rsys/dynamic_array.h>
-#define DARRAY_NAME vertex
-#define DARRAY_DATA struct aw_obj_vertex
-#include <rsys/dynamic_array.h>
-
-static FINLINE char
-vertex_eq(const struct aw_obj_vertex* v0, const struct aw_obj_vertex* v1)
-{
- return f4_eq_eps(v0->position, v1->position, 1.e-6f)
- && f3_eq_eps(v0->normal, v1->normal, 1.e-6f)
- && f3_eq_eps(v0->texcoord, v1->texcoord, 1.e-6f);
-}
-
#define HTABLE_NAME vertex_id
-#define HTABLE_DATA uint64_t
-#define HTABLE_KEY struct aw_obj_vertex
-#define HTABLE_KEY_FUNCTOR_EQ vertex_eq
+#define HTABLE_DATA unsigned
+#define HTABLE_KEY size_t
#include <rsys/hash_table.h>
#define HTABLE_NAME material
@@ -80,196 +63,165 @@ vertex_eq(const struct aw_obj_vertex* v0, const struct aw_obj_vertex* v1)
#define HTABLE_KEY_FUNCTOR_COPY str_copy
#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
#define HTABLE_KEY_FUNCTOR_RELEASE str_release
-#define HTABLE_DATA_FUNCTOR_INIT aw_material_init
-#define HTABLE_DATA_FUNCTOR_COPY aw_material_copy
-#define HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE aw_material_copy_and_release
-#define HTABME_DATA_FUNCTOR_RELEASE aw_material_release
#include <rsys/hash_table.h>
struct s3daw {
- ref_T ref;
- struct mem_allocator* allocator;
- struct logger* logger;
- int verbose;
-
struct aw_obj* loader_obj;
struct aw_mtl* loader_mtl;
struct polygon* polygon;
struct s3d_device* s3d;
+
struct darray_shape shapes;
- /* Scratch data structure used during shape registration */
- struct aw_obj_named_group mtl; /* Material of primitive soup */
- struct darray_size_t indices; /* Triangle indices */
- struct darray_vertex vertices; /* float[3], vertex coordinates */
- struct darray_char mtllib; /* Temp buffer for the mtllib filename */
- struct htable_vertex_id vertices_ids; /* Map a aw_obj_vertex to an id */
- struct htable_material materials; /* Map a material name to an aw_material */
+ int verbose;
+
+ struct mem_allocator* allocator;
+ struct logger* logger;
+ ref_T ref;
+};
+
+struct context {
+ const struct darray_float* positions;
+ const struct darray_uint* indices;
};
/*******************************************************************************
* Helper functions
******************************************************************************/
static void
-get_indices(const unsigned itri, unsigned ids[3], void* ctx)
+get_indices(const unsigned itri, unsigned ids[3], void* context)
{
- struct s3daw* s3daw = ctx;
- const size_t* indices;
- ASSERT(ids && ctx && itri < darray_size_t_size_get(&s3daw->indices)/3);
- indices = darray_size_t_cdata_get(&s3daw->indices) + itri * 3;
- ids[0] = (unsigned)indices[0];
- ids[1] = (unsigned)indices[1];
- ids[2] = (unsigned)indices[2];
+ struct context* ctx = context;
+ const unsigned* indices;
+ ASSERT(ids && ctx && itri < darray_uint_size_get(ctx->indices)/3);
+ indices = darray_uint_cdata_get(ctx->indices) + itri*3;
+ ids[0] = indices[0];
+ ids[1] = indices[1];
+ ids[2] = indices[2];
}
static void
-get_position(const unsigned ivert, float pos[3], void* ctx)
+get_position(const unsigned ivert, float pos[3], void* context)
{
- struct s3daw* s3daw = ctx;
- const struct aw_obj_vertex* vertex;
- ASSERT(ctx && pos && ivert < darray_vertex_size_get(&s3daw->vertices));
- vertex = darray_vertex_cdata_get(&s3daw->vertices) + ivert;
- f3_set(pos, vertex->position);
+ struct context* ctx = context;
+ const float* position;
+ ASSERT(ctx && pos && ivert < darray_float_size_get(ctx->positions)/3);
+ position = darray_float_cdata_get(ctx->positions) + ivert*3;
+ pos[0] = position[0];
+ pos[1] = position[1];
+ pos[2] = position[2];
}
-#ifdef COMPILER_CL
-/* On MSVC mime the dirname POSIX function */
-static INLINE char*
-dirname(char* filename)
+static INLINE void
+shapes_clear(struct darray_shape* shapes)
{
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
- size_t drive_len, dir_len;
- errno_t err;
- ASSERT(filename);
-
- err = _splitpath_s
- (filename, drive, sizeof(drive), dir, sizeof(dir), NULL, 0, NULL, 0);
- ASSERT(err == 0);
- drive_len = strlen(drive);
- dir_len = strlen(dir);
- if(!drive_len && !dir_len) {
- ASSERT(strlen(filename) >= 1);
- filename[0] = '.';
- filename[1] = '\0';
- } else {
- if(dir_len && dir[dir_len - 1] == '/')
- dir[--dir_len] = '\0';
- ASSERT(strlen(filename) >= drive_len + dir_len);
- strncpy(filename, drive, drive_len);
- strncpy(filename + drive_len, dir, dir_len + 1/*'\0'*/);
+ size_t i;
+ ASSERT(shapes);
+ FOR_EACH(i, 0, darray_shape_size_get(shapes)) {
+ S3D(shape_ref_put(darray_shape_data_get(shapes)[i]));
}
- return filename;
-}
-#endif
-
-static INLINE res_T
-get_dirname(const char* filename, struct darray_char* filedir)
-{
- const char* dir;
- size_t dir_len;
- res_T res = RES_OK;
- ASSERT(filename && filedir);
-
- res = darray_char_resize(filedir, strlen(filename) + 1/*'\0'*/);
- if(res != RES_OK) goto error;
-
- strcpy(darray_char_data_get(filedir), filename);
- dir = dirname(darray_char_data_get(filedir));
- dir_len = strlen(dir);
-
- res = darray_char_resize(filedir, dir_len + 1/*'/'*/);
- if(res != RES_OK) goto error;
-
- memmove(darray_char_data_get(filedir), dir, dir_len);
- darray_char_data_get(filedir)[dir_len] = '/';
-
-exit:
- return res;
-error:
- darray_char_clear(filedir);
- goto exit;
+ darray_shape_clear(shapes);
}
static res_T
-shape_register(struct s3daw* s3daw, const struct aw_obj_named_group* obj_mtl)
+shape_register
+ (struct s3daw* s3daw,
+ const struct aw_obj_named_group* obj_mtl,
+ struct darray_float* vertices,
+ struct darray_uint* indices,
+ struct htable_vertex_id* vertices_ids)
{
+ struct context ctx;
struct s3d_vertex_data vertex_data;
struct s3d_shape* shape = NULL;
size_t iface;
size_t ntris, nverts;
-
res_T res = RES_OK;
- ASSERT(s3daw && obj_mtl);
+ ASSERT(s3daw && obj_mtl && vertices && indices && vertices_ids);
/* Reset the scrach shape data */
- darray_vertex_clear(&s3daw->vertices);
- darray_size_t_clear(&s3daw->indices);
- htable_vertex_id_clear(&s3daw->vertices_ids);
+ darray_float_clear(vertices);
+ darray_uint_clear(indices);
+ htable_vertex_id_clear(vertices_ids);
FOR_EACH(iface, obj_mtl->face_id, obj_mtl->face_id + obj_mtl->faces_count) {
struct aw_obj_face face;
struct aw_obj_vertex vertex;
+ struct aw_obj_vertex_data vdata;
const uint32_t* tri_ids;
uint32_t ntri_ids;
size_t ivertex;
size_t i;
- AW(obj_face_get(s3daw->loader_obj, iface, &face));
+ AW(obj_get_face(s3daw->loader_obj, iface, &face));
/* Triangulate the face */
POLYGON(clear(s3daw->polygon));
FOR_EACH(ivertex, face.vertex_id, face.vertex_id + face.vertices_count) {
- AW(obj_vertex_get(s3daw->loader_obj, ivertex, &vertex));
- res = polygon_vertex_add(s3daw->polygon, vertex.position);
+ float position[3];
+ AW(obj_get_vertex(s3daw->loader_obj, ivertex, &vertex));
+ AW(obj_get_vertex_data(s3daw->loader_obj, &vertex, &vdata));
+ position[0] = (float)vdata.position[0];
+ position[1] = (float)vdata.position[1];
+ position[2] = (float)vdata.position[2];
+ res = polygon_vertex_add(s3daw->polygon, position);
if(res != RES_OK) goto error;
}
res = polygon_triangulate(s3daw->polygon, &tri_ids, &ntri_ids);
if(res != RES_OK) goto error;
FOR_EACH(i, 0, ntri_ids) {
- size_t* ivertex_registered;
+ unsigned* ivertex_registered;
/* Define if the obj_face vertex is already registered */
ivertex = tri_ids[i] + face.vertex_id;
- AW(obj_vertex_get(s3daw->loader_obj, ivertex, &vertex));
- ivertex_registered = htable_vertex_id_find(&s3daw->vertices_ids, &vertex);
+ AW(obj_get_vertex(s3daw->loader_obj, ivertex, &vertex));
+ ivertex_registered = htable_vertex_id_find(vertices_ids, &vertex.position_id);
if(ivertex_registered) {
/* Vertex is registered. Simply add its id to the indices */
- res = darray_size_t_push_back(&s3daw->indices, ivertex_registered);
+ res = darray_uint_push_back(indices, ivertex_registered);
if(res != RES_OK) goto error;
} else {
/* Vertex is not registered. Register it and add its id to the indices */
- const size_t ivertex_new = darray_vertex_size_get(&s3daw->vertices);
- res = darray_vertex_push_back(&s3daw->vertices, &vertex);
- if(res != RES_OK) goto error;
- res = darray_size_t_push_back(&s3daw->indices, &ivertex_new);
- if(res != RES_OK) goto error;
- res = htable_vertex_id_set(&s3daw->vertices_ids, &vertex, &ivertex_new);
- if(res != RES_OK) goto error;
+ float position[3];
+ const unsigned ivertex_new = (unsigned)darray_float_size_get(vertices)/3;
+
+ AW(obj_get_vertex_data(s3daw->loader_obj, &vertex, &vdata));
+ position[0] = (float)vdata.position[0];
+ position[1] = (float)vdata.position[1];
+ position[2] = (float)vdata.position[2];
+
+ #define CALL(Func) if((res = Func) != RES_OK) goto error;
+ CALL(darray_float_push_back(vertices, position+0));
+ CALL(darray_float_push_back(vertices, position+1));
+ CALL(darray_float_push_back(vertices, position+2));
+ CALL(darray_uint_push_back(indices, &ivertex_new));
+ CALL(htable_vertex_id_set(vertices_ids, &vertex.position_id, &ivertex_new));
+ #undef CALL
}
}
}
- /* Create the S3D shape */
-
- nverts = darray_vertex_size_get(&s3daw->vertices);
- ntris = darray_size_t_size_get(&s3daw->indices);
- if(!ntris) goto exit;
- ASSERT(!(ntris % 3));
- ntris /= 3;
+ nverts = darray_float_size_get(vertices) / 3;
+ ntris = darray_uint_size_get(indices) / 3;
+ if(!ntris) goto exit; /* Nothing to do */
res = s3d_shape_create_mesh(s3daw->s3d, &shape);
if(res != RES_OK) goto error;
+
vertex_data.usage = S3D_POSITION;
vertex_data.type = S3D_FLOAT3;
vertex_data.get = get_position;
+ ctx.indices = indices;
+ ctx.positions = vertices;
+ /* Setup the S3D mesh data */
res = s3d_mesh_setup_indexed_vertices(shape, (unsigned)ntris, get_indices,
- (unsigned)nverts, &vertex_data, 1, s3daw);
+ (unsigned)nverts, &vertex_data, 1, &ctx);
if(res != RES_OK) goto error;
+ /* Register the shape */
res = darray_shape_push_back(&s3daw->shapes, &shape);
if(res != RES_OK) goto error;
@@ -280,46 +232,27 @@ error:
goto exit;
}
-static void
-materials_clear(struct htable_material* materials)
-{
- struct htable_material_iterator it, end;
- ASSERT(materials);
-
- htable_material_begin(materials, &it);
- htable_material_end(materials, &end);
- while(!htable_material_iterator_eq(&it, &end)) {
- struct aw_material* material = htable_material_iterator_data_get(&it);
- htable_material_iterator_next(&it);
- AW(material_release(material));
- }
- htable_material_clear(materials);
-}
-
-static INLINE void
-shapes_clear(struct darray_shape* shapes)
-{
- size_t i;
- ASSERT(shapes);
- FOR_EACH(i, 0, darray_shape_size_get(shapes)) {
- S3D(shape_ref_put(darray_shape_data_get(shapes)[i]));
- }
- darray_shape_clear(shapes);
-}
-
static res_T
shapes_create(struct s3daw* s3daw, const char* filename)
{
+ struct darray_uint indices;
+ struct darray_float vertices;
+ struct htable_vertex_id vertices_ids;
struct aw_obj_desc obj_desc;
- struct aw_material material;
- size_t imtl;
+ struct aw_obj_named_group grp;
res_T res = RES_OK;
ASSERT(s3daw && filename);
- AW(material_init(s3daw->allocator, &material));
- AW(obj_desc_get(s3daw->loader_obj, &obj_desc));
+ /* Clean up the previously created shapes */
shapes_clear(&s3daw->shapes);
+ /* Init scratch data structures */
+ darray_uint_init(s3daw->allocator, &indices);
+ darray_float_init(s3daw->allocator, &vertices);
+ htable_vertex_id_init(s3daw->allocator, &vertices_ids);
+
+ AW(obj_get_desc(s3daw->loader_obj, &obj_desc));
+
if(obj_desc.faces_count == 0) {
if(s3daw->verbose) {
logger_print(s3daw->logger, LOG_WARNING,
@@ -329,70 +262,27 @@ shapes_create(struct s3daw* s3daw, const char* filename)
}
if(!obj_desc.usemtls_count) { /* No material grouping => triangle soup */
- str_clear(&s3daw->mtl.name);
- s3daw->mtl.face_id = 0;
- s3daw->mtl.faces_count = obj_desc.faces_count;
- res = shape_register(s3daw, &s3daw->mtl);
- if(res != RES_OK) goto error;
- } else {
- size_t imtllib;
- size_t dirname_len;
-
- /* Setup the `mtllib' buffer with the directory of the filename */
- res = get_dirname(filename, &s3daw->mtllib);
+ grp.name = NULL;
+ grp.face_id = 0;
+ grp.faces_count = obj_desc.faces_count;
+ res = shape_register(s3daw, &grp, &vertices, &indices, &vertices_ids);
if(res != RES_OK) goto error;
- dirname_len = darray_char_size_get(&s3daw->mtllib);
-
- /* Load the materials */
- FOR_EACH(imtllib, 0, obj_desc.mtllibs_count) {
- const char* mtllib;
- size_t mtllib_len;
- size_t nmtls;
-
- AW(obj_mtllib_get(s3daw->loader_obj, imtllib, &mtllib));
-
- /* Append the mtllib name to the directory stored into the `mtllib' */
- mtllib_len = strlen(mtllib);
- res = darray_char_resize(&s3daw->mtllib, mtllib_len + 1/*'\0'*/);
- if(res != RES_OK) goto error;
- strncpy(darray_char_data_get(&s3daw->mtllib) + dirname_len,
- mtllib, mtllib_len + 1);
-
- /* Load the material library */
- res = aw_mtl_load(s3daw->loader_mtl, darray_char_cdata_get(&s3daw->mtllib));
- if(res != RES_OK && res != RES_IO_ERR/*The mtl lib may not be found*/)
- goto error;
-
- /* Register the materials of the material library */
- AW(mtl_materials_count_get(s3daw->loader_mtl, &nmtls));
- FOR_EACH(imtl, 0, nmtls) {
- AW(mtl_material_get(s3daw->loader_mtl, imtl, &material));
- res = htable_material_set(&s3daw->materials, &material.name, &material);
- if(res != RES_OK) goto error;
- }
- }
-
- /* Create a S3D shape per material */
+ } else { /* Create a S3D shape per material */
+ size_t imtl;
FOR_EACH(imtl, 0, obj_desc.usemtls_count) {
- const struct aw_material* pmaterial;
- AW(obj_mtl_get(s3daw->loader_obj, imtl, &s3daw->mtl));
- pmaterial = htable_material_find(&s3daw->materials, &s3daw->mtl.name);
- if(!pmaterial) { /* Some material may not be loaded */
- logger_print(s3daw->logger, LOG_WARNING,
- "The material `%s' is not loaded\n", str_cget(&s3daw->mtl.name));
- str_clear(&s3daw->mtl.name);
- }
- res = shape_register(s3daw, &s3daw->mtl);
+ AW(obj_get_mtl(s3daw->loader_obj, imtl, &grp));
+ res = shape_register(s3daw, &grp, &vertices, &indices, &vertices_ids);
if(res != RES_OK) goto error;
}
}
exit:
- AW(material_release(&material));
+ darray_uint_release(&indices);
+ darray_float_release(&vertices);
+ htable_vertex_id_release(&vertices_ids);
return res;
error:
shapes_clear(&s3daw->shapes);
- materials_clear(&s3daw->materials);
goto exit;
}
@@ -401,24 +291,12 @@ release_s3daw(ref_T* ref)
{
struct s3daw* s3daw = CONTAINER_OF(ref, struct s3daw, ref);
ASSERT(ref);
-
if(s3daw->loader_obj) AW(obj_ref_put(s3daw->loader_obj));
if(s3daw->loader_mtl) AW(mtl_ref_put(s3daw->loader_mtl));
if(s3daw->polygon) POLYGON(ref_put(s3daw->polygon));
if(s3daw->s3d) S3D(device_ref_put(s3daw->s3d));
-
shapes_clear(&s3daw->shapes);
- materials_clear(&s3daw->materials);
-
darray_shape_release(&s3daw->shapes);
-
- AW(obj_named_group_release(&s3daw->mtl));
- darray_size_t_release(&s3daw->indices);
- darray_vertex_release(&s3daw->vertices);
- darray_char_release(&s3daw->mtllib);
- htable_vertex_id_release(&s3daw->vertices_ids);
- htable_material_release(&s3daw->materials);
-
MEM_RM(s3daw->allocator, s3daw);
}
@@ -457,12 +335,6 @@ s3daw_create
S3D(device_ref_get(s3d));
s3daw->s3d = s3d;
darray_shape_init(s3daw->allocator, &s3daw->shapes);
- AW(obj_named_group_init(allocator, &s3daw->mtl));
- darray_size_t_init(s3daw->allocator, &s3daw->indices);
- darray_vertex_init(s3daw->allocator, &s3daw->vertices);
- darray_char_init(s3daw->allocator, &s3daw->mtllib);
- htable_vertex_id_init(s3daw->allocator, &s3daw->vertices_ids);
- htable_material_init(s3daw->allocator, &s3daw->materials);
res = polygon_create(s3daw->allocator, &s3daw->polygon);
if(res != RES_OK) goto error;
@@ -546,7 +418,7 @@ s3daw_load_stream(struct s3daw* s3daw, FILE* stream)
if(!s3daw || !stream) return RES_BAD_ARG;
- res = aw_obj_load_stream(s3daw->loader_obj, stream);
+ res = aw_obj_load_stream(s3daw->loader_obj, stream, "stream");
if(res != RES_OK) return res;
return shapes_create(s3daw, "./");
}
@@ -562,12 +434,6 @@ s3daw_clear(struct s3daw* s3daw)
/* Clear shape */
shapes_clear(&s3daw->shapes);
- /* Clear scratch data structures */
- darray_size_t_clear(&s3daw->indices);
- darray_vertex_clear(&s3daw->vertices);
- darray_char_clear(&s3daw->mtllib);
- htable_vertex_id_clear(&s3daw->vertices_ids);
-
AW(obj_clear(s3daw->loader_obj));
AW(mtl_clear(s3daw->loader_mtl));
@@ -583,7 +449,10 @@ s3daw_get_shapes_count(const struct s3daw* s3daw, size_t* nshapes)
}
res_T
-s3daw_get_shape(struct s3daw* s3daw, const size_t ishape, struct s3d_shape** shape)
+s3daw_get_shape
+ (struct s3daw* s3daw,
+ const size_t ishape,
+ struct s3d_shape** shape)
{
if(!s3daw || !shape || ishape >= darray_shape_size_get(&s3daw->shapes))
return RES_BAD_ARG;