commit 6a663a189130e6250ca2cf7171a4399ff84f0fc2
parent 72f383f5f4ce1a6d9dfc931f7a105a1f066abedf
Author: vaplv <vaplv@free.fr>
Date: Fri, 31 Jan 2020 12:18:27 +0100
Full review and refactoring of the code
Use the RSys text reader to parse the input files. Use the RSys cstr
functions to perform text conversions. Use double precision rather than
single precision for floating data. Use "const char*" rather than the
RSys "struct str" data structure to describe strings in the public API.
Add the optional "stream_name" parameter to the aw_<obj|mtl>_load_stream
functions, allowing the user to define the name of the submitted stream.
Update the name of the get functions.
Finally make the "struct aw_obj_vertex" data type a structure containing
the indices of the vertex, not their data. Add the
aw_obj_get_vertex_data function that fetches the data of a given vertex.
By exposing the indices of a vertex, one can uniquely identify a
vertex according to its indices rather than comparing its whole data.
Diffstat:
| M | cmake/CMakeLists.txt | | | 2 | +- |
| M | src/aw.c | | | 75 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
| M | src/aw.h | | | 138 | +++++++++++++++++++++++++------------------------------------------------------ |
| M | src/aw_c.h | | | 60 | +++++++++++++----------------------------------------------- |
| M | src/aw_mtl.c | | | 929 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
| M | src/aw_obj.c | | | 839 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
| M | src/test_aw_mtl.c | | | 320 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
| M | src/test_aw_obj.c | | | 396 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
8 files changed, 1496 insertions(+), 1263 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -26,7 +26,7 @@ set(AW_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
# Dependencies
################################################################################
find_package(RCMake 0.4 REQUIRED)
-find_package(RSys 0.6 REQUIRED)
+find_package(RSys 0.9 REQUIRED)
set(CMAKE_MODULE_PATH ${RCMAKE_SOURCE_DIR})
include(rcmake)
diff --git a/src/aw.c b/src/aw.c
@@ -16,43 +16,86 @@
#define _POSIX_C_SOURCE 200112L /* strtok_r support */
#include "aw_c.h"
+#include <rsys/cstr.h>
+#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
#include <string.h>
/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+print_info(const char* msg, void* ctx)
+{
+ fprintf(stderr, "%s%s", ctx ? (const char*)ctx : "info: ", msg);
+}
+
+static void
+print_err(const char* msg, void* ctx)
+{
+ fprintf(stderr, "%s%s", ctx ? (const char*)ctx : "error: ", msg);
+}
+
+static void
+print_warn(const char* msg, void* ctx)
+{
+ fprintf(stderr, "%s%s", ctx ? (const char*)ctx : "warning: ", msg);
+}
+
+/*******************************************************************************
* Local functions
******************************************************************************/
res_T
-parse_floatX
- (float* f,
+parse_doubleX
+ (double* dblX,
const unsigned int count_min,
const unsigned int count_max,
- const float range_min,
- const float range_max,
- const float default_value,
- char** tk_ctxt)
+ const double range_min,
+ const double range_max,
+ const double default_value,
+ char** tk_ctx)
{
size_t i;
- ASSERT(f && count_min <= count_max && range_min <= range_max && tk_ctxt);
+ ASSERT(dblX && count_min <= count_max && range_min <= range_max && tk_ctx);
ASSERT(default_value >= range_min && default_value <= range_max);
FOR_EACH(i, 0, count_max) {
- char* real;
- res_T res;
- if(NULL == (real = strtok_r(NULL, " ", tk_ctxt)))
- break;
- res = string_to_float(real, f + i);
- if(res != RES_OK)
- return res;
- if(f[i] < range_min || f[i] > range_max)
+ char* real = strtok_r(NULL, " \t", tk_ctx);
+ res_T res = RES_OK;
+
+ if(!real) break;
+
+ res = cstr_to_double(real, dblX + i);
+ if(res != RES_OK) return res;
+
+ if(dblX[i] < range_min || dblX[i] > range_max)
return RES_BAD_ARG;
}
if(i < count_min)
return RES_BAD_ARG;
FOR_EACH(i, i, count_max)
- f[i] = default_value;
+ dblX[i] = default_value;
+
+ return RES_OK;
+}
+res_T
+setup_default_logger
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ const char* prefix_info, /* May be NULL */
+ const char* prefix_error, /* May be NULL */
+ const char* prefix_warning) /* May be NULL */
+{
+ res_T res = RES_OK;
+ ASSERT(logger);
+ res = logger_init(allocator, logger);
+ if(res != RES_OK) return res;
+ logger_set_stream(logger, LOG_OUTPUT, print_info, (void*)prefix_info);
+ logger_set_stream(logger, LOG_ERROR, print_err, (void*)prefix_error);
+ logger_set_stream(logger, LOG_WARNING, print_warn, (void*)prefix_warning);
return RES_OK;
}
+
diff --git a/src/aw.h b/src/aw.h
@@ -73,49 +73,55 @@ struct aw_obj_face {
};
struct aw_obj_named_group {
- struct str name;
- size_t face_id; /* Index of the first group face */
+ const char* name;
+ size_t face_id;
size_t faces_count;
};
struct aw_obj_smooth_group {
- char is_smoothed;
size_t face_id; /* Index of the first smooth group face */
size_t faces_count;
+ char is_smoothed;
};
struct aw_obj_vertex {
- float position[4];
- float normal[3];
- float texcoord[3];
+ size_t position_id;
+ size_t texcoord_id;
+ size_t normal_id;
+};
+
+struct aw_obj_vertex_data {
+ double position[4];
+ double normal[3];
+ double texcoord[3];
};
struct aw_color {
- float value[3];
+ double value[3];
enum aw_color_space color_space;
};
struct aw_map {
- struct str filename; /* str_len == 0 <=> Not defined */
+ const char* filename; /* NULL <=> Not defined */
int options_mask;
- float image_bias; /* Scalar to add to the image pixels */
- float image_scale; /* Scalar to multiply to the image pixels */
- float texcoord_bias[3];
- float texcoord_scale[3];
- float texcoord_turbulence[3];
+ double image_bias; /* Scalar to add to the image pixels */
+ double image_scale; /* Scalar to multiply to the image pixels */
+ double texcoord_bias[3];
+ double texcoord_scale[3];
+ double texcoord_turbulence[3];
size_t resolution; /* image size = resolution x resolution */
enum aw_map_channel scalar; /* Channel used to create a scalar texture */
- float bump_multiplier; /* Only available on bump maps */
+ double bump_multiplier; /* Only available on bump maps */
};
struct aw_material {
- struct str name;
+ const char* name;
struct aw_color ambient;
struct aw_color diffuse;
struct aw_color specular;
struct aw_color transmission;
- float specular_exponent;
- float refraction_index;
+ double specular_exponent;
+ double refraction_index;
size_t illumination_model; /* In [0, 10] */
struct aw_map ambient_map;
struct aw_map diffuse_map;
@@ -157,7 +163,8 @@ aw_obj_load
AW_API res_T
aw_obj_load_stream
(struct aw_obj* obj,
- FILE* stream);
+ FILE* stream,
+ const char* stream_name); /* May be NULL <=> default name, i.e. "stream" */
AW_API res_T
aw_obj_clear
@@ -169,46 +176,52 @@ aw_obj_purge
(struct aw_obj* obj);
AW_API res_T
-aw_obj_desc_get
- (struct aw_obj* obj,
+aw_obj_get_desc
+ (const struct aw_obj* obj,
struct aw_obj_desc* desc);
AW_API res_T
-aw_obj_face_get
+aw_obj_get_face
(const struct aw_obj* obj,
const size_t face_id,
struct aw_obj_face* face);
AW_API res_T
-aw_obj_group_get
+aw_obj_get_group
(const struct aw_obj* obj,
const size_t group_id,
struct aw_obj_named_group* group);
AW_API res_T
-aw_obj_smooth_group_get
+aw_obj_get_smooth_group
(const struct aw_obj* obj,
const size_t smooth_group_id,
struct aw_obj_smooth_group* smooth_group);
AW_API res_T
-aw_obj_mtl_get
+aw_obj_get_mtl
(const struct aw_obj* obj,
const size_t mtl_id,
struct aw_obj_named_group* mtl);
AW_API res_T
-aw_obj_mtllib_get
+aw_obj_get_mtllib
(const struct aw_obj* obj,
const size_t mtllib_id,
const char** mtllib);
AW_API res_T
-aw_obj_vertex_get
+aw_obj_get_vertex
(const struct aw_obj* obj,
const size_t vertex_id,
struct aw_obj_vertex* vertex);
+AW_API res_T
+aw_obj_get_vertex_data
+ (const struct aw_obj* obj,
+ const struct aw_obj_vertex* vertex,
+ struct aw_obj_vertex_data* vertex_data);
+
/*******************************************************************************
* Mtl functions
******************************************************************************/
@@ -235,7 +248,8 @@ aw_mtl_load
AW_API res_T
aw_mtl_load_stream
(struct aw_mtl* mtl,
- FILE* stream);
+ FILE* stream,
+ const char* stream_name); /* May be NULL <=> default name, i.e. "stream" */
AW_API res_T
aw_mtl_clear
@@ -247,83 +261,17 @@ aw_mtl_purge
(struct aw_mtl* mtl);
AW_API res_T
-aw_mtl_materials_count_get
+aw_mtl_get_materials_count
(struct aw_mtl* mtl,
size_t* materials_count);
/* The filled material must be released by the aw_material_release function */
AW_API res_T
-aw_mtl_material_get
+aw_mtl_get_material
(struct aw_mtl* mtl,
const size_t imaterial,
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
-aw_map_init
- (struct mem_allocator* allocator,
- struct aw_map* map);
-
-AW_API res_T
-aw_map_release
- (struct aw_map* map);
-
-AW_API res_T
-aw_map_copy
- (struct aw_map* dst,
- const struct aw_map* src);
-
-AW_API res_T
-aw_map_copy_and_release
- (struct aw_map* dst,
- struct aw_map* src);
-
-/*******************************************************************************
- * Material functions
- ******************************************************************************/
-AW_API res_T
-aw_material_init
- (struct mem_allocator* allocator,
- struct aw_material* material);
-
-AW_API res_T
-aw_material_release
- (struct aw_material* material);
-
-AW_API res_T
-aw_material_copy
- (struct aw_material* dst,
- const struct aw_material* src);
-
-AW_API res_T
-aw_material_copy_and_release
- (struct aw_material* dst,
- struct aw_material* src);
-
END_DECLS
#endif /* AW_H */
diff --git a/src/aw_c.h b/src/aw_c.h
@@ -18,57 +18,23 @@
#include "aw.h"
-static FINLINE res_T
-string_to_float(const char* str, float* f)
-{
- char* ptr = NULL;
- ASSERT(f);
- if(!str)
- return RES_BAD_ARG;
- *f = (float)strtod(str, &ptr);
- if(ptr == str || *ptr != '\0')
- return RES_BAD_ARG;
- return RES_OK;
-}
-
-static FINLINE res_T
-string_to_long(const char* str, long* i)
-{
- char* ptr = NULL;
- ASSERT(i);
- if(!str)
- return RES_BAD_ARG;
- *i = strtol(str, &ptr, 10);
- if(ptr == str || *ptr != '\0')
- return RES_BAD_ARG;
- return RES_OK;
-}
-
-static FINLINE res_T
-string_to_size_t(const char* str, size_t* i)
-{
- long l;
- res_T res;
- ASSERT(i);
-
- res = string_to_long(str, &l);
- if(res != RES_OK)
- return res;
- if(l < 0)
- return RES_BAD_ARG;
- *i = (size_t)l;
- return RES_OK;
-}
-
extern LOCAL_SYM res_T
-parse_floatX
- (float* f,
+parse_doubleX
+ (double* dblX,
const unsigned int count_min,
const unsigned int count_max,
- const float range_min,
- const float range_max,
- const float default_value,
+ const double range_min,
+ const double range_max,
+ const double default_value,
char** tk_ctxt);
+extern LOCAL_SYM res_T
+setup_default_logger
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ const char* prefix_info, /* May be NULL */
+ const char* prefix_error, /* May be NULL */
+ const char* prefix_warning); /* May be NULL */
+
#endif /* AW_C_H */
diff --git a/src/aw_mtl.c b/src/aw_mtl.c
@@ -17,13 +17,13 @@
#include "aw_c.h"
-#include <rsys/clock_time.h>
-#include <rsys/dynamic_array_char.h>
-#include <rsys/float3.h>
+#include <rsys/cstr.h>
+#include <rsys/double3.h>
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
#include <rsys/ref_count.h>
#include <rsys/str.h>
+#include <rsys/text_reader.h>
#include <float.h>
@@ -39,19 +39,196 @@ enum map_type {
};
/*******************************************************************************
- * Definition of the aw_mtl opaque data structure
+ * Map data structure
+ ******************************************************************************/
+struct map {
+ struct str filename; /* str_len == 0 <=> Not defined */
+ int options_mask;
+ double image_bias; /* Scalar to add to the image pixels */
+ double image_scale; /* Scalar to multiply to the image pixels */
+ double texcoord_bias[3];
+ double texcoord_scale[3];
+ double texcoord_turbulence[3];
+ size_t resolution; /* image size = resolution x resolution */
+ enum aw_map_channel scalar; /* Channel used to create a scalar texture */
+ double bump_multiplier; /* Only available on bump maps */
+};
+
+static INLINE void
+map_init(struct mem_allocator* allocator, struct map* map)
+{
+ ASSERT(map);
+ str_init(allocator, &map->filename);
+ map->options_mask = 0;
+ map->image_bias = 0.f;
+ map->image_scale = 1.f;
+ d3_splat(map->texcoord_bias, 0.f);
+ d3_splat(map->texcoord_scale, 1.f);
+ d3_splat(map->texcoord_turbulence, 0.f);
+ map->resolution = 0;
+ map->scalar = AW_MAP_CHANNEL_LUMINANCE;
+ map->bump_multiplier = 1.0f;
+}
+
+static INLINE void
+map_release(struct map* map)
+{
+ ASSERT(map);
+ str_release(&map->filename);
+}
+
+static INLINE void
+map_copy_pod(struct map* dst, const struct map* src)
+{
+ ASSERT(dst && src);
+ dst->options_mask = src->options_mask;
+ dst->image_bias = src->image_bias;
+ dst->image_scale = src->image_scale;
+ d3_set(dst->texcoord_bias, src->texcoord_bias);
+ d3_set(dst->texcoord_scale, src->texcoord_scale);
+ d3_set(dst->texcoord_turbulence, src->texcoord_turbulence);
+ dst->resolution = src->resolution;
+ dst->scalar = src->scalar;
+ dst->bump_multiplier = src->bump_multiplier;
+}
+
+static INLINE res_T
+map_copy(struct map* dst, const struct map* src)
+{
+ map_copy_pod(dst, src);
+ return str_copy(&dst->filename, &src->filename);
+}
+
+static INLINE res_T
+map_copy_and_release(struct map* dst, struct map* src)
+{
+ map_copy_pod(dst, src);
+ return str_copy_and_release(&dst->filename, &src->filename);
+}
+
+static INLINE void
+map_to_aw_map(const struct map* map, struct aw_map* aw_map)
+{
+ ASSERT(map && aw_map);
+ aw_map->filename = str_is_empty(&map->filename) ? NULL : str_cget(&map->filename);
+ aw_map->options_mask = map->options_mask;
+ aw_map->image_bias = map->image_bias;
+ aw_map->image_scale = map->image_scale;
+ d3_set(aw_map->texcoord_bias, map->texcoord_bias);
+ d3_set(aw_map->texcoord_scale, map->texcoord_scale);
+ d3_set(aw_map->texcoord_turbulence, map->texcoord_turbulence);
+ aw_map->resolution = map->resolution;
+ aw_map->scalar = map->scalar;
+ aw_map->bump_multiplier = map->bump_multiplier;
+}
+
+/*******************************************************************************
+ * Material API
******************************************************************************/
+struct material {
+ struct str name;
+ struct aw_color ambient;
+ struct aw_color diffuse;
+ struct aw_color specular;
+ struct aw_color transmission;
+ double specular_exponent;
+ double refraction_index;
+ size_t illumination_model; /* In [0, 10] */
+ struct map ambient_map;
+ struct map diffuse_map;
+ struct map specular_map;
+ struct map specular_exponent_map; /* Scalar texture */
+ struct map bump_map; /* Scalar texture with valid bump multiplier */
+};
+
+static INLINE void
+material_init(struct mem_allocator* allocator, struct material* mtl)
+{
+ ASSERT(mtl);
+ memset(mtl, 0, sizeof(struct aw_material));
+ str_init(allocator, &mtl->name);
+ map_init(allocator, &mtl->ambient_map);
+ map_init(allocator, &mtl->diffuse_map);
+ map_init(allocator, &mtl->specular_map);
+ map_init(allocator, &mtl->specular_exponent_map);
+ map_init(allocator, &mtl->bump_map);
+}
+
+static INLINE void
+material_release(struct material* mtl)
+{
+ ASSERT(mtl);
+ str_release(&mtl->name);
+ map_release(&mtl->ambient_map);
+ map_release(&mtl->diffuse_map);
+ map_release(&mtl->specular_map);
+ map_release(&mtl->specular_exponent_map);
+ map_release(&mtl->bump_map);
+}
+
+static INLINE void
+material_copy_pod(struct material* dst, const struct material* src)
+{
+ ASSERT(dst && src);
+ dst->ambient = src->ambient;
+ dst->diffuse = src->diffuse;
+ dst->specular = src->specular;
+ dst->transmission = src->transmission;
+ dst->specular_exponent = src->specular_exponent;
+ dst->refraction_index = src->refraction_index;
+ dst->illumination_model = src->illumination_model;
+}
+
+static INLINE res_T
+material_copy(struct material* dst, const struct material* src)
+{
+ res_T res = RES_OK;
+ ASSERT(dst && src);
+ material_copy_pod(dst, src);
+ #define CALL(Func) if(RES_OK != (res = Func)) return res
+ CALL(str_copy(&dst->name, &src->name));
+ CALL(map_copy(&dst->ambient_map, &src->ambient_map));
+ CALL(map_copy(&dst->diffuse_map, &src->diffuse_map));
+ CALL(map_copy(&dst->specular_map, &src->specular_map));
+ CALL(map_copy(&dst->specular_exponent_map, &src->specular_exponent_map));
+ CALL(map_copy(&dst->bump_map, &src->bump_map));
+ #undef CALL
+ return RES_OK;
+}
+
+static INLINE res_T
+material_copy_and_release(struct material* dst, struct material* src)
+{
+ res_T res = RES_OK;
+ ASSERT(dst && src);
+ material_copy_pod(dst, src);
+ #define CALL(Func) if(RES_OK != (res = Func)) return res
+ CALL(str_copy_and_release(&dst->name, &src->name));
+ CALL(map_copy_and_release(&dst->ambient_map, &src->ambient_map));
+ CALL(map_copy_and_release(&dst->diffuse_map, &src->diffuse_map));
+ CALL(map_copy_and_release(&dst->specular_map, &src->specular_map));
+ CALL(map_copy_and_release
+ (&dst->specular_exponent_map, &src->specular_exponent_map));
+ CALL(map_copy_and_release(&dst->bump_map, &src->bump_map));
+ #undef CALL
+ return RES_OK;
+}
+
/* Generate the darray_mtl data structure */
#define DARRAY_NAME material
-#define DARRAY_DATA struct aw_material
-#define DARRAY_FUNCTOR_INIT aw_material_init
-#define DARRAY_FUNCTOR_RELEASE aw_material_release
-#define DARRAY_FUNCTOR_COPY aw_material_copy
+#define DARRAY_DATA struct material
+#define DARRAY_FUNCTOR_INIT material_init
+#define DARRAY_FUNCTOR_RELEASE material_release
+#define DARRAY_FUNCTOR_COPY material_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE material_copy_and_release
#include <rsys/dynamic_array.h>
+/*******************************************************************************
+ * Definition of the aw_mtl opaque data structure
+ ******************************************************************************/
struct aw_mtl {
struct darray_material materials;
- struct aw_material* newmtl; /* Pointer toward the current material */
+ struct material* newmtl; /* Pointer toward the current material */
const char* filename; /* Currently parsed file. Use in error messages */
size_t iline; /* Currently parsed line index. Use in error messages */
@@ -59,117 +236,160 @@ struct aw_mtl {
ref_T ref;
struct mem_allocator* allocator;
struct logger* logger;
+ struct logger logger__; /* Default logger */
int verbose;
};
/*******************************************************************************
* Helper functions
******************************************************************************/
-static INLINE res_T
-parse_name(struct str* name, char* tk, char** tk_ctxt)
+static INLINE void
+log_msg
+ (const struct aw_mtl* mtl,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
{
- res_T res = RES_OK;
- ASSERT(tk_ctxt && name);
-
- if(!tk) {
- res = RES_BAD_ARG;
- goto error;
+ ASSERT(mtl && msg);
+ if(mtl->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(mtl->logger, stream, msg, vargs);
+ ASSERT(res == RES_OK);
}
- str_clear(name);
- do {
- res = str_append(name, tk);
- if(res != RES_OK) goto error;
- } while((tk = strtok_r(NULL, " \t", tk_ctxt)));
+}
-exit:
- return res;
-error:
- str_clear(name);
- goto exit;
+static INLINE void
+log_err(const struct aw_mtl* mtl, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(mtl && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(mtl, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+static INLINE void
+log_warn(const struct aw_mtl* mtl, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(mtl && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(mtl, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
}
static res_T
-parse_newmtl(struct aw_mtl* mtl, char** word_tk)
+parse_newmtl(struct aw_mtl* mtl, char** tk_ctx)
{
- char* word;
+ struct material* newmtl = NULL;
+ char* tk = NULL;
size_t nmtls;
- res_T res;
- ASSERT(mtl && word_tk);
+ res_T res = RES_OK;
+ ASSERT(mtl && tk_ctx);
- word = strtok_r(NULL, "\n", word_tk);
- if(!word)
- return RES_BAD_ARG;
+ tk = strtok_r(NULL, " \t", tk_ctx); /* Blanks are prohibited in mtl name */
+ if(!tk) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
nmtls = darray_material_size_get(&mtl->materials);
+
+ /* Allocate the new material */
res = darray_material_resize(&mtl->materials, nmtls + 1);
- if(res != RES_OK)
- return res;
+ if(res != RES_OK) goto error;
- mtl->newmtl = darray_material_data_get(&mtl->materials) + nmtls;
- res = parse_name(&mtl->newmtl->name, word, word_tk);
- if(res != RES_OK) {
- darray_material_pop_back(&mtl->materials);
- mtl->newmtl = NULL;
- return res;
- }
+ /* Fetch the new material */
+ newmtl = darray_material_data_get(&mtl->materials) + nmtls;
+
+ /* Setup the material name */
+ res = str_set(&newmtl->name, tk);
+ if(res != RES_OK) goto error;
+
+ /* Set the new material as the material to parse */
+ mtl->newmtl = newmtl;
+
+exit:
return RES_OK;
+error:
+ if(newmtl) darray_material_pop_back(&mtl->materials);
+ goto exit;
}
static res_T
-parse_color(struct aw_mtl* mtl, struct aw_color* col, char** word_tk)
+parse_color(struct aw_mtl* mtl, struct aw_color* col, char** tk_ctx)
{
- char* word;
+ char* tk = NULL;
res_T res = RES_OK;
- ASSERT(mtl && col && word_tk);
+ ASSERT(mtl && col && tk_ctx);
- word = strtok_r(NULL, " \t", word_tk);
- if(!word)
- return RES_BAD_ARG;
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
- if(!strcmp(word, "spectral")) {
- if(mtl->verbose) {
- logger_print
- (mtl->logger, LOG_ERROR, "spectral colors are not supported\n");
- }
- return RES_BAD_ARG;
+ if(!strcmp(tk, "spectral")) {
+ log_err(mtl, "spectral colors are not supported\n");
+ res = RES_BAD_ARG;
+ goto error;
}
- col->color_space = strcmp(word, "xyz") == 0 ? AW_COLOR_XYZ : AW_COLOR_RGB;
- if(col->color_space == AW_COLOR_XYZ
- && !(word = strtok_r(NULL, " \t", word_tk)))
- return RES_BAD_ARG;
+ if(strcmp(tk, "xyz")) {
+ col->color_space = AW_COLOR_RGB;
+ } else {
+ col->color_space = AW_COLOR_XYZ;
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
- if(RES_OK != (res = string_to_float(word, &col->value[0])))
- return res;
+ res = cstr_to_double(tk, &col->value[0]);
+ if(res != RES_OK) goto error;
/* If only the first component is defined the second and third components are
* assumed to be equal to the first one */
- word = strtok_r(NULL, " \t", word_tk);
- if(!word) {
- col->value[1] = col->value[2] = col->value[0];
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) {
+ col->value[1] = col->value[0];
+ col->value[2] = col->value[0];
} else {
- if(RES_OK != (res = string_to_float(word, &col->value[1])))
- return res;
- word = strtok_r(NULL, " \t", word_tk);
- if(RES_OK != (res = string_to_float(word, &col->value[2])))
- return res;
+ res = cstr_to_double(tk, &col->value[1]);
+ if(res != RES_OK) goto error;
+
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) { res = RES_BAD_ARG; goto error; }
+
+ res = cstr_to_double(tk, &col->value[2]);
+ if(res == RES_OK) goto error;
}
- return RES_OK;
+
+exit:
+ return res;
+error:
+ goto exit;
}
static INLINE res_T
parse_size_t
- (size_t* s, const size_t range_min, const size_t range_max, char** word_tk)
+ (size_t* s, const size_t range_min, const size_t range_max, char** tk_ctx)
{
- char* word;
+ unsigned long ul;
+ char* tk = NULL;
res_T res = RES_OK;
- ASSERT(s && word_tk && range_min < range_max);
+ ASSERT(s && tk_ctx && range_min < range_max);
- word = strtok_r(NULL, "\n", word_tk);
- if(RES_OK != (res = string_to_size_t(word, s)))
- return res;
- if(range_min > *s || range_max < *s)
- return RES_BAD_ARG;
+ tk = strtok_r(NULL, "\n", tk_ctx);
+ if(!tk) return res;
+
+ res = cstr_to_ulong(tk, &ul);
+ if(res != RES_OK) return res;
+ if((unsigned long)range_min > ul || (unsigned long)range_max < ul) return res;
+ *s = ul;
return RES_OK;
}
@@ -177,40 +397,44 @@ static res_T
parse_bool_option
(int* options_mask,
const enum aw_map_flag option,
- char** tk_ctxt)
+ char** tk_ctx)
{
- char* word;
- ASSERT(options_mask && tk_ctxt);
- word = strtok_r(NULL, " \t", tk_ctxt);
- if(!word)
- return RES_BAD_ARG;
- if(strcmp(word, "on") == 0) {
+ char* tk;
+ ASSERT(options_mask && tk_ctx);
+
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) return RES_BAD_ARG;
+
+ if(!strcmp(tk, "on")) {
*options_mask |= (int)option;
- } else if(strcmp(word, "off") != 0) {
+ } else if(!strcmp(tk, "off")) {
+ *options_mask &= ~((int)option);
+ } else {
return RES_BAD_ARG;
}
return RES_OK;
}
static FINLINE res_T
-parse_imfchan_option(enum aw_map_channel* channel, char** tk_ctxt)
+parse_imfchan_option(enum aw_map_channel* channel, char** tk_ctx)
{
- char* word;
- ASSERT(channel && tk_ctxt);
- word = strtok_r(NULL, " \t", tk_ctxt);
- if(!word)
- return RES_BAD_ARG;
- if(!strcmp(word, "r")) {
+ char* tk = NULL;
+ ASSERT(channel && tk_ctx);
+
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) return RES_BAD_ARG;
+
+ if(!strcmp(tk, "r")) {
*channel = AW_MAP_CHANNEL_RED;
- } else if(!strcmp(word, "g")) {
+ } else if(!strcmp(tk, "g")) {
*channel = AW_MAP_CHANNEL_GREEN;
- } else if(!strcmp(word, "b")) {
+ } else if(!strcmp(tk, "b")) {
*channel = AW_MAP_CHANNEL_BLUE;
- } else if(!strcmp(word, "m")) {
+ } else if(!strcmp(tk, "m")) {
*channel = AW_MAP_CHANNEL_MATTE;
- } else if(!strcmp(word, "l")) {
+ } else if(!strcmp(tk, "l")) {
*channel = AW_MAP_CHANNEL_LUMINANCE;
- } else if(!strcmp(word, "z")) {
+ } else if(!strcmp(tk, "z")) {
*channel = AW_MAP_CHANNEL_DEPTH;
} else {
return RES_BAD_ARG;
@@ -219,166 +443,182 @@ parse_imfchan_option(enum aw_map_channel* channel, char** tk_ctxt)
}
static res_T
-parse_map
- (struct aw_map* map,
- const enum map_type type,
- char** tk_ctxt)
-{
- char* word;
- ASSERT(map && tk_ctxt);
-
- word = strtok_r(NULL, " \t", tk_ctxt);
- while(word) {
- res_T res;
-
- if(!strcmp(word, "-blendu")) {
- res = parse_bool_option(&map->options_mask, AW_MAP_BLEND_U, tk_ctxt);
- } else if(!strcmp(word, "-blendv")) {
- res = parse_bool_option(&map->options_mask, AW_MAP_BLEND_V, tk_ctxt);
- } else if(!strcmp(word, "-cc")) {
+parse_map(struct map* map, const enum map_type type, char** tk_ctx)
+{
+ char* tk = NULL;
+ res_T res = RES_OK;
+ ASSERT(map && tk_ctx);
+
+ for(;;) {
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(!strcmp(tk, "-blendu")) {
+ res = parse_bool_option(&map->options_mask, AW_MAP_BLEND_U, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-blendv")) {
+ res = parse_bool_option(&map->options_mask, AW_MAP_BLEND_V, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-cc")) {
res = parse_bool_option
- (&map->options_mask, AW_MAP_COLOR_CORRECTION, tk_ctxt);
- } else if(!strcmp(word, "-clamp")) {
- res = parse_bool_option(&map->options_mask, AW_MAP_CLAMP, tk_ctxt);
- } else if(!strcmp(word, "-imfchan") && (type & MAP_SCALAR)) {
- res = parse_imfchan_option(&map->scalar, tk_ctxt);
- } else if(!strcmp(word, "-mm")) { /* Image bias and scale */
- res = parse_floatX
- (&map->image_bias, 1, 1, -FLT_MAX, FLT_MAX, 0.f, tk_ctxt);
- if(res == RES_OK) {
- res = parse_floatX
- (&map->image_scale, 1, 1, -FLT_MAX, FLT_MAX, 0.f, tk_ctxt);
+ (&map->options_mask, AW_MAP_COLOR_CORRECTION, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-clamp")) {
+ res = parse_bool_option(&map->options_mask, AW_MAP_CLAMP, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-imfchan") && (type & MAP_SCALAR)) {
+ res = parse_imfchan_option(&map->scalar, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-mm")) { /* Image bias and scale */
+ res = parse_doubleX
+ (&map->image_bias, 1, 1, -DBL_MAX, DBL_MAX, 0.f, tk_ctx);
+ if(res != RES_OK) goto error;
+ res = parse_doubleX
+ (&map->image_scale, 1, 1, -DBL_MAX, DBL_MAX, 0.f, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-o")) { /* Texcoord offset */
+ res = parse_doubleX
+ (map->texcoord_bias, 1, 3, -DBL_MAX, DBL_MAX, 0.f, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-s")) { /* Texcoord scale */
+ res = parse_doubleX
+ (map->texcoord_scale, 1, 3, -DBL_MAX, DBL_MAX, 1.f, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-t")) { /* Texcoord turbulence */
+ res = parse_doubleX
+ (map->texcoord_turbulence, 1, 3, -DBL_MAX, DBL_MAX, 0.f, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-texres")) { /* Texture resolution */
+ res = parse_size_t(&map->resolution, 1, SIZE_MAX, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(tk, "-bm") && (type == MAP_BUMP)) {/* Bump multiplier */
+ res = parse_doubleX
+ (&map->bump_multiplier, 1, 1, -DBL_MAX, DBL_MAX, 0.f, tk_ctx);
+ if(res != RES_OK) goto error;
+ } else { /* Map filename */
+ res = str_set(&map->filename, tk);
+ if(res != RES_OK) goto error;
+ tk = strtok_r(NULL, "", tk_ctx);
+ if(tk) {
+ res = str_append_char(&map->filename, ' ');
+ if(res != RES_OK) goto error;
+ res = str_append(&map->filename, strtok_r(NULL, "", tk_ctx));
+ if(res != RES_OK) goto error;
}
- } else if(!strcmp(word, "-o")) { /* Texcoord offset */
- res = parse_floatX
- (map->texcoord_bias, 1, 3, -FLT_MAX, FLT_MAX, 0.f, tk_ctxt);
- } else if(!strcmp(word, "-s")) { /* Texcoord scale */
- res = parse_floatX
- (map->texcoord_scale, 1, 3, -FLT_MAX, FLT_MAX, 1.f, tk_ctxt);
- } else if(!strcmp(word, "-t")) { /* Texcoord turbulence */
- res = parse_floatX
- (map->texcoord_turbulence, 1, 3,-FLT_MAX, FLT_MAX, 0.f, tk_ctxt);
- } else if(!strcmp(word, "-texres")) { /* Texture resolution */
- res = parse_size_t(&map->resolution, 1, SIZE_MAX, tk_ctxt);
- } else if(!strcmp(word, "-bm") && (type == MAP_BUMP)) {/* Bump multiplier */
- res = parse_floatX
- (&map->bump_multiplier, 1, 1, -FLT_MAX, FLT_MAX, 0.f, tk_ctxt);
- } else {
- res = parse_name(&map->filename, word, tk_ctxt);
+ break; /* The map is fully parsed */
}
- if(res != RES_OK)
- return res;
- word = strtok_r(NULL, " \t", tk_ctxt);
}
- return RES_OK;
+
+exit:
+ return res;
+error:
+ goto exit;
}
static res_T
-parse_mtl_line(struct aw_mtl* mtl, char* line)
+parse_mtl_line(struct aw_mtl* mtl, struct txtrdr* txtrdr)
{
+ char* tk = NULL;
+ char* tk_ctx = NULL;
res_T res = RES_OK;
- char* word, *word_tk;
- ASSERT(mtl && line);
-
- word = strtok_r(line, " \t", &word_tk);
- if(word) {
- if(word[0] == '#') { /* Comment */
- goto exit;
- } else if(!strcmp(word, "newmtl")) { /* Material name declaration */
- res = parse_newmtl(mtl, &word_tk);
- } else if(mtl->newmtl == NULL) {
- res = RES_BAD_ARG;
- } else if(!strcmp(word, "Ka")) { /* Ambient reflectivity */
- res = parse_color(mtl, &mtl->newmtl->ambient, &word_tk);
- } else if(!strcmp(word, "Kd")) { /* Diffuse reflectivity */
- res = parse_color(mtl, &mtl->newmtl->diffuse, &word_tk);
- } else if(!strcmp(word, "Ks")) { /* Specular reflectivity */
- res = parse_color(mtl, &mtl->newmtl->specular, &word_tk);
- } else if(!strcmp(word, "Tf")) { /* Transimission filter */
- res = parse_color(mtl, &mtl->newmtl->transmission, &word_tk);
- } else if(!strcmp(word, "Ns")) { /* Specular exponent */
- res = parse_floatX
- (&mtl->newmtl->specular_exponent, 1, 1, 0.f, FLT_MAX, 0.f, &word_tk);
- } else if(!strcmp(word, "Ni")) { /* Refraction index */
- res = parse_floatX
- (&mtl->newmtl->refraction_index, 1, 1, 0.001f, 10.f, 0.001f,&word_tk);
- } else if(!strcmp(word, "illum")) { /* Illumination model */
- res = parse_size_t(&mtl->newmtl->illumination_model, 0, 10, &word_tk);
- } else if(!strcmp(word, "map_Ka")) { /* Ambient texture */
- res = parse_map(&mtl->newmtl->ambient_map, MAP_COMMON, &word_tk);
- } else if(!strcmp(word, "map_Kd")) { /* Diffuse texture */
- res = parse_map(&mtl->newmtl->diffuse_map, MAP_COMMON, &word_tk);
- } else if(!strcmp(word, "map_Ks")) { /* Specular texture */
- res = parse_map(&mtl->newmtl->specular_map, MAP_COMMON, &word_tk);
- } else if(!strcmp(word, "map_Ns")) { /* Specular exponent texture */
- res = parse_map
- (&mtl->newmtl->specular_exponent_map, MAP_SCALAR, &word_tk);
- } else if(!strcmp(word, "bump")) { /* Bump map */
- res = parse_map(&mtl->newmtl->bump_map, MAP_BUMP, &word_tk);
- } else {
- res = RES_OK;
- if(mtl->verbose) {
- logger_print(mtl->logger, LOG_WARNING,
- "%s:%lu: warning: ignored or malformed directive %s\n",
- mtl->filename, (unsigned long)mtl->iline, word);
- }
- while((word = strtok_r(NULL, " \t", &word_tk))); /* Skip spaces */
- }
- if(res != RES_OK)
- goto error;
- if((word = strtok_r(NULL, " ", &word_tk))) {
- if(mtl->verbose) {
- logger_print(mtl->logger, LOG_ERROR, "%s:%lu: unexpected directive %s\n",
- mtl->filename, (unsigned long)mtl->iline, word);
- }
- res = RES_BAD_ARG;
- goto error;
- }
+ ASSERT(mtl && txtrdr);
+
+ tk = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx);
+ ASSERT(tk); /* A line should exist since it was parsed by txtrdr */
+
+ if(!strcmp(tk, "newmtl")) { /* Material name declaration */
+ res = parse_newmtl(mtl, &tk_ctx);
+ } else if(mtl->newmtl == NULL) {
+ res = RES_BAD_ARG;
+ } else if(!strcmp(tk, "Ka")) { /* Ambient reflectivity */
+ res = parse_color(mtl, &mtl->newmtl->ambient, &tk_ctx);
+ } else if(!strcmp(tk, "Kd")) { /* Diffuse reflectivity */
+ res = parse_color(mtl, &mtl->newmtl->diffuse, &tk_ctx);
+ } else if(!strcmp(tk, "Ks")) { /* Specular reflectivity */
+ res = parse_color(mtl, &mtl->newmtl->specular, &tk_ctx);
+ } else if(!strcmp(tk, "Tf")) { /* Transimission filter */
+ res = parse_color(mtl, &mtl->newmtl->transmission, &tk_ctx);
+ } else if(!strcmp(tk, "Ns")) { /* Specular exponent */
+ res = parse_doubleX
+ (&mtl->newmtl->specular_exponent, 1, 1, 0, DBL_MAX, 0, &tk_ctx);
+ } else if(!strcmp(tk, "Ni")) { /* Refraction index */
+ res = parse_doubleX
+ (&mtl->newmtl->refraction_index, 1, 1, 0.001, 10, 0.001, &tk_ctx);
+ } else if(!strcmp(tk, "illum")) { /* Illumination model */
+ res = parse_size_t(&mtl->newmtl->illumination_model, 0, 10, &tk_ctx);
+ } else if(!strcmp(tk, "map_Ka")) { /* Ambient texture */
+ res = parse_map(&mtl->newmtl->ambient_map, MAP_COMMON, &tk_ctx);
+ } else if(!strcmp(tk, "map_Kd")) { /* Diffuse texture */
+ res = parse_map(&mtl->newmtl->diffuse_map, MAP_COMMON, &tk_ctx);
+ } else if(!strcmp(tk, "map_Ks")) { /* Specular texture */
+ res = parse_map(&mtl->newmtl->specular_map, MAP_COMMON, &tk_ctx);
+ } else if(!strcmp(tk, "map_Ns")) { /* Specular exponent texture */
+ res = parse_map
+ (&mtl->newmtl->specular_exponent_map, MAP_SCALAR, &tk_ctx);
+ } else if(!strcmp(tk, "bump")) { /* Bump map */
+ res = parse_map(&mtl->newmtl->bump_map, MAP_BUMP, &tk_ctx);
+ } else {
+ log_warn(mtl,
+ "%s:%lu: warning: ignored or malformed directive `%s'\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ strtok_r(NULL, "", &tk_ctx); /* Discard remaining text */
+ }
+ if(res != RES_OK) {
+ log_err(mtl, "%s:%lu: parsing failed.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ goto error;
}
+
+ tk = strtok_r(NULL, "", &tk_ctx);
+ if(tk) {
+ log_err(mtl, "%s:%lu: unexpected text `%s'.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
exit:
return res;
error:
- if(mtl->verbose) {
- logger_print(mtl->logger, LOG_ERROR, "%s:%lu: error: parsing failed\n",
- mtl->filename, (unsigned long)mtl->iline);
- }
goto exit;
}
-static void
-mtl_clear(struct aw_mtl* mtl)
+static res_T
+load_stream(struct aw_mtl* mtl, FILE* stream, const char* stream_name)
{
- ASSERT(mtl);
- darray_material_clear(&mtl->materials);
- mtl->newmtl = NULL;
-}
+ struct txtrdr* txtrdr = NULL;
+ res_T res = RES_OK;
+ ASSERT(mtl && stream && stream_name);
-static FINLINE void
-map_copy_pod__(struct aw_map* dst, const struct aw_map* src)
-{
- ASSERT(dst && src);
- dst->options_mask = src->options_mask;
- dst->image_bias = src->image_bias;
- dst->image_scale = src->image_scale;
- f3_set(dst->texcoord_bias, src->texcoord_bias);
- f3_set(dst->texcoord_scale, src->texcoord_scale);
- f3_set(dst->texcoord_turbulence, src->texcoord_turbulence);
- dst->resolution = src->resolution;
- dst->scalar = src->scalar;
- dst->bump_multiplier = src->bump_multiplier;
-}
+ res = txtrdr_stream(mtl->allocator, stream, stream_name, '#', &txtrdr);
+ if(res != RES_OK) {
+ log_err(mtl, "Could not create the text reader.\n");
+ goto error;
+ }
-static FINLINE void
-material_copy_pod__(struct aw_material* dst, const struct aw_material* src)
-{
- ASSERT(dst && src);
- dst->ambient = src->ambient;
- dst->diffuse = src->diffuse;
- dst->specular = src->specular;
- dst->transmission = src->transmission;
- dst->specular_exponent = src->specular_exponent;
- dst->refraction_index = src->refraction_index;
- dst->illumination_model = src->illumination_model;
+ for(;;) {
+ res = txtrdr_read_line(txtrdr);
+ if(res != RES_OK) {
+ log_err(mtl, "%s: could not read the line `%lu'.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
+ goto error;
+ }
+
+ if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */
+
+ res = parse_mtl_line(mtl, txtrdr);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ if(txtrdr) txtrdr_ref_put(txtrdr);
+ return res;
+error:
+ AW(mtl_clear(mtl));
+ goto exit;
}
static void
@@ -387,6 +627,7 @@ mtl_release(ref_T* ref)
struct aw_mtl* mtl = CONTAINER_OF(ref, struct aw_mtl, ref);
ASSERT(ref);
darray_material_release(&mtl->materials);
+ if(mtl->logger == &mtl->logger__) logger_release(&mtl->logger__);
MEM_RM(mtl->allocator, mtl);
}
@@ -416,13 +657,20 @@ aw_mtl_create
}
ref_init(&mtl->ref);
mtl->allocator = allocator;
- mtl->logger = logger ? logger : LOGGER_DEFAULT;
mtl->verbose = verbose;
darray_material_init(allocator, &mtl->materials);
+ if(logger) {
+ mtl->logger = logger;
+ } else {
+ res = setup_default_logger(mtl->allocator, &mtl->logger__,
+ "load-mtl:info: ", "load-mtl:error: ", "load-mtl:warning: ");
+ if(res != RES_OK) goto error;
+ mtl->logger = &mtl->logger__;
+ }
+
exit:
- if(mtl_out)
- *mtl_out = mtl;
+ if(mtl_out) *mtl_out = mtl;
return res;
error:
if(mtl) {
@@ -451,80 +699,47 @@ aw_mtl_ref_put(struct aw_mtl* mtl)
res_T
aw_mtl_load(struct aw_mtl* mtl, const char* filename)
{
- FILE* file;
+ FILE* file = NULL;
res_T res = RES_OK;
- if(!mtl || !filename)
- return RES_BAD_ARG;
+ if(!mtl || !filename) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
- mtl->filename = filename;
file = fopen(filename, "r");
if(!file) {
- if(mtl->verbose)
- logger_print(mtl->logger, LOG_ERROR, "Error opening `%s'\n", filename);
- return RES_IO_ERR;
+ log_err(mtl, "Error opening `%s'\n", filename);
+ res = RES_IO_ERR;
+ goto error;
}
- res = aw_mtl_load_stream(mtl, file);
- mtl->filename = NULL;
- fclose(file);
+ res = load_stream(mtl, file, filename);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(file) fclose(file);
return res;
+error:
+ goto exit;
}
res_T
-aw_mtl_load_stream(struct aw_mtl* mtl, FILE* stream)
+aw_mtl_load_stream(struct aw_mtl* mtl, FILE* stream, const char* stream_name)
{
- char* line;
- struct darray_char buf;
- const unsigned buf_chunk = 256;
res_T res = RES_OK;
- /* Avoid zealous "may be used uninitialized" warning of GCC 4.9.2 */
- memset(&buf, 0, sizeof(buf));
-
if(!mtl || !stream) {
res = RES_BAD_ARG;
goto error;
}
- darray_char_init(mtl->allocator, &buf);
-
- res = darray_char_resize(&buf, buf_chunk);
- if(res != RES_OK)
- goto error;
-
- if(!mtl->filename)
- mtl->filename = "stream";
- mtl->iline = 1;
- mtl_clear(mtl);
- while((line = fgets
- (darray_char_data_get(&buf), (int)darray_char_size_get(&buf), stream))) {
- size_t last_char;
-
- while(!strrchr(line,'\n')) { /* Ensure that the whole line was read */
- res = darray_char_resize(&buf, darray_char_size_get(&buf) + buf_chunk);
- if(res != RES_OK)
- goto error;
- line = darray_char_data_get(&buf);
- if(!fgets(line + strlen(line), (int)buf_chunk, stream)) /* EOF */
- break;
- }
- /* Remove the newline character(s) */
- last_char = strlen(line);
- while(last_char-- && (line[last_char]=='\n' || line[last_char]=='\r'));
- line[last_char + 1] = '\0';
- if(RES_OK != (res = parse_mtl_line(mtl, line)))
- goto error;
- ++mtl->iline;
- }
+ res = load_stream(mtl, stream, stream_name ? stream_name : "stream");
+ if(res != RES_OK) goto error;
exit:
- if(mtl && stream)
- darray_char_release(&buf);
return res;
error:
- if(mtl)
- mtl_clear(mtl);
goto exit;
}
@@ -547,7 +762,7 @@ aw_mtl_purge(struct aw_mtl* mtl)
}
res_T
-aw_mtl_materials_count_get(struct aw_mtl* mtl, size_t* nmtls)
+aw_mtl_get_materials_count(struct aw_mtl* mtl, size_t* nmtls)
{
if(!mtl || !nmtls)
return RES_BAD_ARG;
@@ -556,122 +771,30 @@ aw_mtl_materials_count_get(struct aw_mtl* mtl, size_t* nmtls)
}
res_T
-aw_mtl_material_get
+aw_mtl_get_material
(struct aw_mtl* mtl,
const size_t imaterial,
struct aw_material* material)
{
- const struct aw_material* mtr;
+ const struct material* mat = NULL;
+
if(!mtl || !material || imaterial>=darray_material_size_get(&mtl->materials))
return RES_BAD_ARG;
- mtr = darray_material_cdata_get(&mtl->materials) + imaterial;
- return aw_material_copy(material, mtr);
-}
-res_T
-aw_map_init(struct mem_allocator* allocator, struct aw_map* map)
-{
- if(!map) return RES_BAD_ARG;
- str_init(allocator, &map->filename);
- map->options_mask = 0;
- map->image_bias = 0.f;
- map->image_scale = 1.f;
- f3_splat(map->texcoord_bias, 0.f);
- f3_splat(map->texcoord_scale, 1.f);
- f3_splat(map->texcoord_turbulence, 0.f);
- map->resolution = 0;
- map->scalar = AW_MAP_CHANNEL_LUMINANCE;
- map->bump_multiplier = 1.0f;
- return RES_OK;
-}
-
-res_T
-aw_map_release(struct aw_map* map)
-{
- if(!map) return RES_BAD_ARG;
- str_release(&map->filename);
- return RES_OK;
-}
-
-res_T
-aw_map_copy(struct aw_map* dst, const struct aw_map* src)
-{
- if(!dst || !src) return RES_BAD_ARG;
- if(dst == src) return RES_OK;
- map_copy_pod__(dst, src);
- return str_copy(&dst->filename, &src->filename);
-}
-
-res_T
-aw_map_copy_and_release(struct aw_map* dst, struct aw_map* src)
-{
- if(!dst || !src) return RES_BAD_ARG;
- if(dst == src) return RES_OK;
- map_copy_pod__(dst, src);
- return str_copy_and_release(&dst->filename, &src->filename);
-}
-
-res_T
-aw_material_init(struct mem_allocator* allocator, struct aw_material* mtl)
-{
- if(!mtl) return RES_BAD_ARG;
- memset(mtl, 0, sizeof(struct aw_material));
- str_init(allocator, &mtl->name);
- AW(map_init(allocator, &mtl->ambient_map));
- AW(map_init(allocator, &mtl->diffuse_map));
- AW(map_init(allocator, &mtl->specular_map));
- AW(map_init(allocator, &mtl->specular_exponent_map));
- AW(map_init(allocator, &mtl->bump_map));
- return RES_OK;
-}
-
-res_T
-aw_material_release(struct aw_material* mtl)
-{
- if(!mtl) return RES_BAD_ARG;
- str_release(&mtl->name);
- AW(map_release(&mtl->ambient_map));
- AW(map_release(&mtl->diffuse_map));
- AW(map_release(&mtl->specular_map));
- AW(map_release(&mtl->specular_exponent_map));
- AW(map_release(&mtl->bump_map));
- return RES_OK;
-}
-
-res_T
-aw_material_copy(struct aw_material* dst, const struct aw_material* src)
-{
- res_T res;
- if(!dst || !src) return RES_BAD_ARG;
- if(dst == src) return RES_OK;
- material_copy_pod__(dst, src);
- #define CALL(Func) if(RES_OK != (res = Func)) return res
- CALL(str_copy(&dst->name, &src->name));
- CALL(aw_map_copy(&dst->ambient_map, &src->ambient_map));
- CALL(aw_map_copy(&dst->diffuse_map, &src->diffuse_map));
- CALL(aw_map_copy(&dst->specular_map, &src->specular_map));
- CALL(aw_map_copy(&dst->specular_exponent_map, &src->specular_exponent_map));
- CALL(aw_map_copy(&dst->bump_map, &src->bump_map));
- #undef CALL
- return RES_OK;
-}
-
-res_T
-aw_material_copy_and_release(struct aw_material* dst, struct aw_material* src)
-{
- res_T res;
- if(!dst || !src) return RES_BAD_ARG;
- if(dst == src) return RES_OK;
- material_copy_pod__(dst, src);
- #define CALL(Func) if(RES_OK != (res = Func)) return res
- CALL(str_copy_and_release(&dst->name, &src->name));
- CALL(aw_map_copy_and_release(&dst->ambient_map, &src->ambient_map));
- CALL(aw_map_copy_and_release(&dst->diffuse_map, &src->diffuse_map));
- CALL(aw_map_copy_and_release(&dst->specular_map, &src->specular_map));
- CALL(aw_map_copy_and_release
- (&dst->specular_exponent_map, &src->specular_exponent_map));
- CALL(aw_map_copy_and_release(&dst->bump_map, &src->bump_map));
- #undef CALL
+ mat = darray_material_cdata_get(&mtl->materials) + imaterial;
+ material->name = str_cget(&mat->name);
+ material->ambient = mat->ambient;
+ material->diffuse = mat->diffuse;
+ material->specular = mat->specular;
+ material->transmission = mat->transmission;
+ material->specular_exponent = mat->specular_exponent;
+ material->refraction_index = mat->refraction_index;
+ material->illumination_model = mat->illumination_model;
+ map_to_aw_map(&mat->ambient_map, &material->ambient_map);
+ map_to_aw_map(&mat->diffuse_map, &material->diffuse_map);
+ map_to_aw_map(&mat->specular_map, &material->specular_map);
+ map_to_aw_map(&mat->specular_exponent_map, &material->specular_exponent_map);
+ map_to_aw_map(&mat->bump_map, &material->bump_map);
return RES_OK;
}
diff --git a/src/aw_obj.c b/src/aw_obj.c
@@ -17,33 +17,25 @@
#include "aw_c.h"
-#include <rsys/clock_time.h>
-#include <rsys/dynamic_array_char.h>
-#include <rsys/dynamic_array_float.h>
-#include <rsys/float3.h>
-#include <rsys/float4.h>
+#include <rsys/cstr.h>
+#include <rsys/dynamic_array_double.h>
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
#include <rsys/ref_count.h>
#include <rsys/str.h>
+#include <rsys/text_reader.h>
-#include <float.h>
+#include <float.h> /* DBL_MAX & DBL_MIN definition */
+#include <stdarg.h>
#ifdef COMPILER_CL
#pragma warning(push)
#pragma warning(disable:4706) /* Assignment within a condition */
#endif
-struct vertex {
- size_t iposition;
- size_t inormal;
- size_t itexcoord;
-};
-static const struct vertex VERTEX_NULL = { AW_ID_NONE, AW_ID_NONE, AW_ID_NONE };
-
/* Generate the darray_vertex data structure */
#define DARRAY_NAME vertex
-#define DARRAY_DATA struct vertex
+#define DARRAY_DATA struct aw_obj_vertex
#include <rsys/dynamic_array.h>
/* Generate the darray_face data structure */
@@ -51,13 +43,56 @@ static const struct vertex VERTEX_NULL = { AW_ID_NONE, AW_ID_NONE, AW_ID_NONE };
#define DARRAY_DATA struct aw_obj_face
#include <rsys/dynamic_array.h>
+static const struct aw_obj_vertex VERTEX_NULL = {
+ AW_ID_NONE, AW_ID_NONE, AW_ID_NONE
+};
+
+struct named_group {
+ struct str name;
+ size_t face_id; /* Index of the first group face */
+ size_t faces_count;
+};
+
+static INLINE void
+named_group_init(struct mem_allocator* allocator, struct named_group* grp)
+{
+ str_init(allocator, &grp->name);
+}
+
+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);
+ 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);
+}
+
+static INLINE res_T
+named_group_copy_and_release(struct named_group* dst, struct named_group* src)
+{
+ ASSERT(dst && src);
+ 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);
+}
+
/* Generate the darray_named_group data structure */
#define DARRAY_NAME named_group
-#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
+#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
#include <rsys/dynamic_array.h>
/* Generate the darray_smooth_group data structure */
@@ -75,9 +110,9 @@ static const struct vertex VERTEX_NULL = { AW_ID_NONE, AW_ID_NONE, AW_ID_NONE };
#include <rsys/dynamic_array.h>
struct aw_obj {
- struct darray_float positions; /* float4 */
- struct darray_float normals; /* float3 */
- struct darray_float texcoords; /* float3 */
+ struct darray_double positions; /* double4 */
+ struct darray_double normals; /* double3 */
+ struct darray_double texcoords; /* double3 */
struct darray_vertex vertices;
struct darray_face faces;
struct darray_named_group groups;
@@ -87,90 +122,141 @@ struct aw_obj {
size_t igroups_active; /* Index toward the first active group */
- const char* filename; /* Currently parsed file. Use in messages */
- size_t iline; /* Currently parsed line index. Use in messages */
-
ref_T ref;
struct mem_allocator* allocator;
struct logger* logger;
+ struct logger logger__; /* Default logger */
int verbose;
};
/*******************************************************************************
* Helper functions
******************************************************************************/
-static FINLINE void
+static INLINE void
+log_msg
+ (const struct aw_obj* obj,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(obj && msg);
+ if(obj->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(obj->logger, stream, msg, vargs);
+ ASSERT(res == RES_OK);
+ }
+}
+
+static INLINE void
+log_err(const struct aw_obj* obj, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(obj && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(obj, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+static INLINE void
+log_warn(const struct aw_obj* obj, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(obj && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(obj, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+static INLINE void
flush_groups(struct aw_obj* obj)
{
size_t nfaces, ngrps;
ASSERT(obj);
- if(0 == (nfaces = darray_face_size_get(&obj->faces)))
- return;
- if(0 == (ngrps = darray_named_group_size_get(&obj->groups)))
- return;
- if(obj->igroups_active >= ngrps)
- return;
+
+ nfaces = darray_face_size_get(&obj->faces);
+ if(!nfaces) return; /* No face to flush */
+
+ ngrps = darray_named_group_size_get(&obj->groups);
+ if(!ngrps) return; /* No group */
+
+ /* There should be an active group to flush if ngrps is not null */
+ ASSERT(obj->igroups_active < ngrps);
+
+ /* Setup the number of faces of each active group */
FOR_EACH(obj->igroups_active, obj->igroups_active, ngrps) {
- struct aw_obj_named_group* grp;
+ struct named_group* grp;
grp = darray_named_group_data_get(&obj->groups) + obj->igroups_active;
ASSERT(grp->face_id <= nfaces);
grp->faces_count = nfaces - grp->face_id;
}
}
-static FINLINE void
+static INLINE void
flush_usemtl(struct aw_obj* obj)
{
- struct aw_obj_named_group* mtl;
+ struct named_group* mtl;
size_t nfaces, ngrps;
ASSERT(obj);
- if(0 == (nfaces = darray_face_size_get(&obj->faces)))
- return;
- if(0 == (ngrps = darray_named_group_size_get(&obj->usemtls)))
- return;
+
+ nfaces = darray_face_size_get(&obj->faces);
+ if(!nfaces) return; /* No face to flush */
+
+ ngrps = darray_named_group_size_get(&obj->usemtls);
+ if(!ngrps) return; /* No group */
+
+ /* Setup the number of faces of the current mtl */
mtl = darray_named_group_data_get(&obj->usemtls) + (ngrps - 1);
ASSERT(mtl->face_id <= nfaces);
mtl->faces_count = nfaces - mtl->face_id;
}
-static FINLINE void
+static INLINE void
flush_smooth_group(struct aw_obj* obj)
{
struct aw_obj_smooth_group* grp;
size_t nfaces, ngrps;
ASSERT(obj);
- if(0 == (nfaces = darray_face_size_get(&obj->faces)))
- return;
- if(0 == (ngrps = darray_smooth_group_size_get(&obj->smooth_groups)))
- return;
+
+ nfaces = darray_face_size_get(&obj->faces);
+ if(!nfaces) return; /* No face to flush */
+
+ ngrps = darray_smooth_group_size_get(&obj->smooth_groups);
+ if(!ngrps) return; /* No smooth group */
+
+ /* Setup the number of faces of the current smoothed group */
grp = darray_smooth_group_data_get(&obj->smooth_groups) + (ngrps - 1);
ASSERT(grp->face_id <= nfaces);
grp->faces_count = nfaces - grp->face_id;
}
static res_T
-parse_floatX_in_darray
- (struct darray_float* darray,
+parse_doubleX_in_darray
+ (struct darray_double* darray,
const unsigned int count_min,
const unsigned int count_max,
- const float default_value,
- char** tk_ctxt)
+ const double default_value,
+ char** tk_ctx)
{
- res_T res;
+ res_T res = RES_OK;
size_t i;
ASSERT(darray);
- i = darray_float_size_get(darray);
- res = darray_float_resize(darray, i + count_max);
- if(res != RES_OK)
- return res;
+ i = darray_double_size_get(darray);
+
+ res = darray_double_resize(darray, i + count_max);
+ if(res != RES_OK) goto error;
- res = parse_floatX
- (darray_float_data_get(darray) + i,
- count_min, count_max, -FLT_MAX, FLT_MAX, default_value, tk_ctxt);
- if(res != RES_OK)
- darray_float_resize(darray, i);
+ res = parse_doubleX(darray_double_data_get(darray) + i, count_min, count_max,
+ -DBL_MAX, DBL_MAX, default_value, tk_ctx);
+ if(res != RES_OK) goto error;
+
+exit:
return res;
+error:
+ darray_double_resize(darray, i);
+ goto exit;
}
static res_T
@@ -182,7 +268,7 @@ string_to_vertex_id
long id_long;
res_T res;
- res = string_to_long(str, &id_long);
+ res = cstr_to_long(str, &id_long);
if(res != RES_OK) return res;
if(id_long > 0) {
@@ -201,252 +287,349 @@ string_to_vertex_id
}
static res_T
-parse_face(struct aw_obj* obj, char** word_tk)
+parse_face_vertex
+ (struct aw_obj* obj,
+ struct aw_obj_face* face,
+ char* str)
{
- struct aw_obj_face face;
- char* word;
+ struct aw_obj_vertex vert = VERTEX_NULL;
+ char* tk1 = NULL;
+ char* tk2 = NULL;
+ char* tk3 = NULL;
+ char* tk_ctx = NULL;
+ size_t npositions = 0;
+ size_t nnormals = 0;
+ size_t ntexcoords = 0;
res_T res = RES_OK;
- ASSERT(obj && word_tk);
+ ASSERT(obj && face && str);
+
+ npositions = darray_double_size_get(&obj->positions) / 4;
+ nnormals = darray_double_size_get(&obj->normals) / 3;
+ ntexcoords = darray_double_size_get(&obj->texcoords) / 3;
+
#define CALL(Func) if(RES_OK != (res = Func)) goto error
+ /* Parse the position */
+ tk1 = strtok_r(str, "/", &tk_ctx);
+ ASSERT(tk1);
+ CALL(string_to_vertex_id(tk1, npositions, &vert.position_id));
+
+ tk2 = strtok_r(NULL, "/", &tk_ctx);
+ if(tk2) {
+ tk1 += strlen(tk1);
+ if(tk2 > tk1 + 3) { /* Unexpected N `/' separators with N > 2 */
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(tk2 == tk1 + 2) { /* `//' separator => No tex */
+ /* Parse the normal */
+ CALL(string_to_vertex_id(tk2, nnormals, &vert.normal_id));
+ } else {
+ /* Parse the texcoords and */
+ CALL(string_to_vertex_id(tk2, ntexcoords, &vert.texcoord_id));
+
+ tk3 = strtok_r(NULL, "", &tk_ctx);
+ if(tk3) {
+ /* Parse the normal */
+ CALL(string_to_vertex_id(tk3, nnormals, &vert.normal_id));
+ }
+ }
+ }
+
+ /* Register the vertex */
+ CALL(darray_vertex_push_back(&obj->vertices, &vert));
+ ++face->vertices_count;
+
+ #undef CALL
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_face(struct aw_obj* obj, char** tk_ctx)
+{
+ struct aw_obj_face face;
+ char* tk = NULL;
+ res_T res = RES_OK;
+ ASSERT(obj && tk_ctx);
+
face.vertex_id = darray_vertex_size_get(&obj->vertices);
face.vertices_count = 0;
face.group_id = darray_named_group_size_get(&obj->groups) - 1;
face.smooth_group_id = darray_smooth_group_size_get(&obj->smooth_groups) - 1;
face.mtl_id = darray_named_group_size_get(&obj->usemtls) - 1;
- while((word = strtok_r(NULL, " \t", word_tk))) {
- char* id, *id_tk, *id_pos;
- struct vertex vert = VERTEX_NULL;
- const size_t positions_count = darray_float_size_get(&obj->positions) / 4;
- const size_t normals_count = darray_float_size_get(&obj->normals) / 3;
- const size_t texcoords_count = darray_float_size_get(&obj->texcoords) / 3;
-
- /* position index */
- id_pos = strtok_r(word, "/", &id_tk);
- CALL(string_to_vertex_id(id_pos, positions_count, &vert.iposition));
- if((id = strtok_r(NULL, "/", &id_tk))) {
- id_pos += strlen(id_pos);
- if(id > id_pos + 3) /* Unexpected N `/' separators with N > 2 */
- goto error;
- if(id == id_pos + 2) { /* `//' separator => No tex */
- /* normal index */
- CALL(string_to_vertex_id(id, normals_count, &vert.inormal));
- } else {
- /* texcoord index */
- CALL(string_to_vertex_id(id, texcoords_count, &vert.itexcoord));
- /* normal index */
- if((id = strtok_r(NULL, "/", &id_tk))) {
- CALL(string_to_vertex_id(id, normals_count, &vert.inormal));
- }
- }
- }
- CALL(darray_vertex_push_back(&obj->vertices, &vert));
- ++face.vertices_count;
+ while((tk = strtok_r(NULL, " \t", tk_ctx))) {
+ res = parse_face_vertex(obj, &face, tk);
+ if(res != RES_OK) goto error;
}
- CALL(darray_face_push_back(&obj->faces, &face));
- #undef CALL
+ /* Register the face */
+ res = darray_face_push_back(&obj->faces, &face);
+ if(res != RES_OK) goto error;
+
exit:
return res;
error:
- FOR_EACH_REVERSE(face.vertices_count, face.vertices_count, 0)
- darray_vertex_pop_back(&obj->vertices);
+ /* Release the registered faces */
+ CHK(darray_vertex_resize(&obj->vertices, face.vertex_id) == RES_OK);
goto exit;
}
static res_T
-parse_group(struct aw_obj* obj, char** word_tk)
+parse_group(struct aw_obj* obj, char** tk_ctx)
{
- char* word;
- size_t ngrps = 0, igrp = 0;
+ char* tk;
+ size_t ngrps = 0;
+ size_t igrp = 0;
res_T res = RES_OK;
- ASSERT(obj && word_tk);
+ ASSERT(obj && tk_ctx);
flush_groups(obj);
- word = strtok_r(NULL, " \t", word_tk);
ngrps = igrp = darray_named_group_size_get(&obj->groups);
- obj->igroups_active = ngrps;
+ obj->igroups_active = igrp;
+
+ tk = strtok_r(NULL, " \t", tk_ctx); /* May be NULL */
+
do {
- struct aw_obj_named_group* grp = NULL;
+ struct named_group* grp = NULL;
+
+ /* Allocate a group */
res = darray_named_group_resize(&obj->groups, igrp + 1);
- if(res != RES_OK)
- goto error;
- grp = darray_named_group_data_get(&obj->groups) + ngrps;
+ if(res != RES_OK) goto error;
+
+ /* Fetch the group */
+ grp = darray_named_group_data_get(&obj->groups) + igrp;
++igrp;
- res = str_set(&grp->name, word ? word : "default");
- if(res != RES_OK)
- goto error;
+
+ /* Setup the group name */
+ res = str_set(&grp->name, tk ? tk : "default");
+ if(res != RES_OK) goto error;
+
+ /* Initialize the group face indices */
grp->face_id = darray_face_size_get(&obj->faces);
grp->faces_count = 0;
- } while((word = strtok_r(NULL, " \t", word_tk)));
+ } while((tk = strtok_r(NULL, " \t", tk_ctx)));
exit:
return res;
error:
- if(igrp != ngrps)
- CHK(darray_named_group_resize(&obj->groups, ngrps) == RES_OK);
+ /* Release the created groups */
+ CHK(darray_named_group_resize(&obj->groups, ngrps) == RES_OK);
goto exit;
}
static res_T
-parse_smooth_group(struct aw_obj* obj, char** word_tk)
+parse_smooth_group(struct aw_obj* obj, char** tk_ctx)
{
- char* word;
struct aw_obj_smooth_group grp;
+ char* tk = NULL;
res_T res;
- size_t i;
- ASSERT(obj && word_tk);
+ ASSERT(obj && tk_ctx);
flush_smooth_group(obj);
- word = strtok_r(NULL, " \t", word_tk);
- if(!strcmp(word, "off")) {
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) return RES_BAD_ARG;
+
+ if(!strcmp(tk, "off")) {
grp.is_smoothed = 0;
- } else if(!strcmp(word, "on")) {
+ } else if(!strcmp(tk, "on")) {
grp.is_smoothed = 1;
} else {
- res = string_to_size_t(word, &i);
- if(res != RES_OK)
- return res;
+ int i;
+ res = cstr_to_int(tk, &i);
+ if(res != RES_OK) return res;
grp.is_smoothed = i != 0;
}
+
+ /* Initialize the smoot group face indices */
grp.face_id = darray_face_size_get(&obj->faces);
grp.faces_count = 0;
+ /* Register the smooth group */
res = darray_smooth_group_push_back(&obj->smooth_groups, &grp);
- if(res != RES_OK)
- return res;
+ if(res != RES_OK) return res;
return RES_OK;
}
static res_T
-parse_mtllib(struct aw_obj* obj, char** word_tk)
+parse_mtllib(struct aw_obj* obj, char** tk_ctx)
{
- char* word;
+ char* tk = NULL;
size_t imtllib = 0;
size_t nmtllibs = 0;
res_T res = RES_OK;
- ASSERT(obj && word_tk);
+ ASSERT(obj && tk_ctx);
- word = strtok_r(NULL, " \t", word_tk);
- if(!word) {
+ nmtllibs = imtllib = darray_mtllib_size_get(&obj->mtllibs);
+
+ tk = strtok_r(NULL, " \t", tk_ctx);
+ if(!tk) {
res = RES_BAD_ARG;
goto error;
}
- nmtllibs = imtllib = darray_mtllib_size_get(&obj->mtllibs);
+
do {
- struct str* str;
+ struct str* str = NULL;
+
+ /* Allocate the mtllib path */
res = darray_mtllib_resize(&obj->mtllibs, imtllib + 1);
- if(res != RES_OK)
- goto error;
+ if(res != RES_OK) goto error;
+
+ /* Fetc the mtllib path */
str = darray_mtllib_data_get(&obj->mtllibs) + imtllib;
++imtllib;
- res = str_set(str, word);
- if(res != RES_OK)
- goto error;
- } while((word = strtok_r(NULL, " \t", word_tk)));
+
+ /* Setup the mtllib name */
+ res = str_set(str, tk);
+ if(res != RES_OK) goto error;
+
+ } while((tk = strtok_r(NULL, " \t", tk_ctx)));
exit:
return res;
error:
- if(imtllib != nmtllibs)
- CHK(darray_mtllib_resize(&obj->mtllibs, nmtllibs) == RES_OK);
+ CHK(darray_mtllib_resize(&obj->mtllibs, nmtllibs) == RES_OK);
goto exit;
}
static res_T
-parse_usemtl(struct aw_obj* obj, char** word_tk)
+parse_usemtl(struct aw_obj* obj, char** tk_ctx)
{
- char* word;
- struct aw_obj_named_group* mtl = NULL;
+ char* tk = NULL;
+ struct named_group* mtl = NULL;
size_t nmtls;
res_T res = RES_OK;
- ASSERT(obj && word_tk);
+ ASSERT(obj && tk_ctx);
flush_usemtl(obj);
- word= strtok_r(NULL, " \t", word_tk);
- if(!word_tk) {
+ tk = strtok_r(NULL, " \t", tk_ctx); /* Blanks are prohibited in mtl name */
+ if(!tk) {
res = RES_BAD_ARG;
goto error;
}
nmtls = darray_named_group_size_get(&obj->usemtls);
+
+ /* Allocate the material */
res = darray_named_group_resize(&obj->usemtls, nmtls + 1);
- if(res != RES_OK)
- goto error;
+ if(res != RES_OK) goto error;
+
+ /* Fetch the material */
mtl = darray_named_group_data_get(&obj->usemtls) + nmtls;
- res = str_set(&mtl->name, word);
- if(res != RES_OK)
- goto error;
+
+ /* Setup the material name */
+ res = str_set(&mtl->name, tk);
+ if(res != RES_OK) goto error;
+
+ /* Initialize the material face indices */
mtl->face_id = darray_face_size_get(&obj->faces);
mtl->faces_count = 0;
exit:
return res;
error:
- if(mtl)
- darray_named_group_pop_back(&obj->usemtls);
+ if(mtl) darray_named_group_pop_back(&obj->usemtls);
goto exit;
}
static res_T
-parse_obj_line(struct aw_obj* obj, char* line)
+parse_obj_line(struct aw_obj* obj, struct txtrdr* txtrdr)
{
- char* word, *word_tk;
+ char* tk = NULL;
+ char* tk_ctx = NULL;
res_T res = RES_OK;
- ASSERT(obj && line);
-
- word = strtok_r(line, " \t", &word_tk);
- if(word) {
- if(word[0] == '#') { /* Comment */
- goto exit;
- } else if(!strcmp(word, "v")) { /* Vertex position */
- res = parse_floatX_in_darray(&obj->positions, 3, 4, 1.f, &word_tk);
- } else if(!strcmp(word, "vn")) { /* Vertex normal */
- res = parse_floatX_in_darray(&obj->normals, 3, 3, 0.f, &word_tk);
- } else if(!strcmp(word, "vt")) { /* Vertex texture coordinates */
- res = parse_floatX_in_darray(&obj->texcoords, 1, 3, 0.f, &word_tk);
- } else if(!strcmp(word, "f") || !strcmp(word, "fo")) { /* face element */
- res = parse_face(obj, &word_tk);
- } else if(!strcmp(word, "g")) { /* Grouping */
- res = parse_group(obj, &word_tk);
- } else if(!strcmp(word, "s")) { /* Smooth group */
- res = parse_smooth_group(obj, &word_tk);
- } else if(!strcmp(word, "mtllib")) { /* Mtl library */
- res = parse_mtllib(obj, &word_tk);
- } else if(!strcmp(word, "usemtl")) { /* Use the mtl library */
- res = parse_usemtl(obj, &word_tk);
- } else {
- res = RES_OK;
- if(obj->verbose) {
- logger_print(obj->logger, LOG_WARNING,
- "%s:%lu: warning: ignored or malformed directive %s\n",
- obj->filename, (unsigned long)obj->iline, word);
- }
- while((word = strtok_r(NULL, " \t", &word_tk))); /* Skip the line */
- }
- if(res != RES_OK)
- goto error;
- if((word = strtok_r(NULL, " ", &word_tk))) {
- if(obj->verbose) {
- logger_print(obj->logger, LOG_ERROR, "%s:%lu: unexpected directive %s\n",
- obj->filename, (unsigned long)obj->iline, word);
- }
- res = RES_BAD_ARG;
+ ASSERT(obj && txtrdr);
+
+ tk = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx);
+ ASSERT(tk); /* A line should exist since it was parsed by txtrdr */
+
+ if(!strcmp(tk, "v")) { /* Vertex position */
+ res = parse_doubleX_in_darray(&obj->positions, 3, 4, 1.f, &tk_ctx);
+ } else if(!strcmp(tk, "vn")) { /* Vertex normal */
+ res = parse_doubleX_in_darray(&obj->normals, 3, 3, 0.f, &tk_ctx);
+ } else if(!strcmp(tk, "vt")) { /* Vertex texture coordinates */
+ res = parse_doubleX_in_darray(&obj->texcoords, 1, 3, 0.f, &tk_ctx);
+ } else if(!strcmp(tk, "f") || !strcmp(tk, "fo")) { /* face element */
+ res = parse_face(obj, &tk_ctx);
+ } else if(!strcmp(tk, "g")) { /* Grouping */
+ res = parse_group(obj, &tk_ctx);
+ } else if(!strcmp(tk, "s")) { /* Smooth group */
+ res = parse_smooth_group(obj, &tk_ctx);
+ } else if(!strcmp(tk, "mtllib")) { /* Mtl library */
+ res = parse_mtllib(obj, &tk_ctx);
+ } else if(!strcmp(tk, "usemtl")) { /* Use the mtl library */
+ res = parse_usemtl(obj, &tk_ctx);
+ } else {
+ log_warn(obj,
+ "%s:%lu: warning: ignored or malformed directive `%s'.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ strtok_r(NULL, "", &tk_ctx); /* Discard remaining text */
+ }
+ if(res != RES_OK) {
+ log_err(obj, "%s:%lu: parsing failed.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
+ goto error;
+ }
+
+ tk = strtok_r(NULL, "", &tk_ctx);
+ if(tk) {
+ log_err(obj, "%s:%lu: unexpected text `%s'.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+load_stream(struct aw_obj* obj, FILE* stream, const char* stream_name)
+{
+ struct txtrdr* txtrdr = NULL;
+ res_T res = RES_OK;
+ ASSERT(obj && stream && stream_name);
+
+ AW(obj_clear(obj));
+
+ res = txtrdr_stream(obj->allocator, stream, stream_name, '#', &txtrdr);
+ if(res != RES_OK) {
+ log_err(obj, "Could not create the text reader.\n");
+ goto error;
+ }
+
+ for(;;) {
+ res = txtrdr_read_line(txtrdr);
+ if(res != RES_OK) {
+ log_err(obj, "%s: could not read the line `%lu'.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
goto error;
}
+
+ if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */
+
+ res = parse_obj_line(obj, txtrdr);
+ if(res != RES_OK) goto error;
}
+
+ flush_groups(obj);
+ flush_smooth_group(obj);
+ flush_usemtl(obj);
exit:
+ if(txtrdr) txtrdr_ref_put(txtrdr);
return res;
error:
- if(obj->verbose) {
- logger_print(obj->logger, LOG_ERROR, "%s:%lu: error: parsing failed\n",
- obj->filename, (unsigned long)obj->iline);
- }
+ AW(obj_clear(obj));
goto exit;
}
@@ -455,15 +638,16 @@ obj_release(ref_T* ref)
{
struct aw_obj* obj = CONTAINER_OF(ref, struct aw_obj, ref);
ASSERT(ref);
- darray_float_release(&obj->positions);
- darray_float_release(&obj->normals);
- darray_float_release(&obj->texcoords);
+ darray_double_release(&obj->positions);
+ darray_double_release(&obj->normals);
+ darray_double_release(&obj->texcoords);
darray_vertex_release(&obj->vertices);
darray_face_release(&obj->faces);
darray_named_group_release(&obj->groups);
darray_named_group_release(&obj->usemtls);
darray_smooth_group_release(&obj->smooth_groups);
darray_mtllib_release(&obj->mtllibs);
+ if(obj->logger == &obj->logger__) logger_release(&obj->logger__);
MEM_RM(obj->allocator, obj);
}
@@ -493,11 +677,10 @@ aw_obj_create
}
ref_init(&obj->ref);
obj->allocator = allocator;
- obj->logger = logger ? logger : LOGGER_DEFAULT;
obj->verbose = verbose;
- darray_float_init(mem_allocator, &obj->positions);
- darray_float_init(mem_allocator, &obj->normals);
- darray_float_init(mem_allocator, &obj->texcoords);
+ darray_double_init(mem_allocator, &obj->positions);
+ darray_double_init(mem_allocator, &obj->normals);
+ darray_double_init(mem_allocator, &obj->texcoords);
darray_vertex_init(mem_allocator, &obj->vertices);
darray_face_init(mem_allocator, &obj->faces);
darray_named_group_init(mem_allocator, &obj->groups);
@@ -505,6 +688,15 @@ aw_obj_create
darray_smooth_group_init(mem_allocator, &obj->smooth_groups);
darray_mtllib_init(mem_allocator, &obj->mtllibs);
+ if(logger) {
+ obj->logger = logger;
+ } else {
+ res = setup_default_logger(obj->allocator, &obj->logger__,
+ "load-obj:info: ", "load-obj:error: ", "load-obj:warning: ");
+ if(res != RES_OK) goto error;
+ obj->logger = &obj->logger__;
+ }
+
exit:
if(obj_out)
*obj_out = obj;
@@ -536,82 +728,47 @@ aw_obj_ref_put(struct aw_obj* obj)
res_T
aw_obj_load(struct aw_obj* obj, const char* filename)
{
- FILE* file;
+ FILE* fp = NULL;
res_T res = RES_OK;
- if(!obj || !filename)
- return RES_BAD_ARG;
+ if(!obj || !filename) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
- obj->filename = filename;
- file = fopen(filename, "r");
- if(!file) {
- if(obj->verbose)
- logger_print(obj->logger, LOG_ERROR, "Error opening `%s'\n", filename);
- return RES_IO_ERR;
+ fp = fopen(filename, "r");
+ if(!fp) {
+ log_err(obj, "Error opening `%s'.\n", filename);
+ res = RES_IO_ERR;
+ goto error;
}
- res = aw_obj_load_stream(obj, file);
- obj->filename = NULL;
- fclose(file);
+
+ res = load_stream(obj, fp, filename);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(fp) fclose(fp);
return res;
+error:
+ goto exit;
}
res_T
-aw_obj_load_stream(struct aw_obj* obj, FILE* stream)
+aw_obj_load_stream(struct aw_obj* obj, FILE* stream, const char* stream_name)
{
- char* line;
- struct darray_char buf;
- const unsigned buf_chunk = 256;
res_T res = RES_OK;
- /* Avoid zealous "may be used uninitialized" warning of GCC 4.9.2 */
- memset(&buf, 0, sizeof(buf));
-
if(!obj || !stream) {
res = RES_BAD_ARG;
goto error;
}
- darray_char_init(obj->allocator, &buf);
- res = darray_char_resize(&buf, buf_chunk);
- if(res != RES_OK)
- goto error;
+ res = load_stream(obj, stream, stream_name ? stream_name : "stream");
+ if(res != RES_OK) goto error;
- if(!obj->filename)
- obj->filename = "stream";
- obj->iline = 1;
- AW(obj_clear(obj));
- while((line = fgets
- (darray_char_data_get(&buf), (int)darray_char_size_get(&buf), stream))) {
- size_t last_char;
-
- while(!strrchr(line,'\n')) { /* Ensure that the whole line was read */
- res = darray_char_resize(&buf, darray_char_size_get(&buf) + buf_chunk);
- if(res != RES_OK)
- goto error;
-
- line = darray_char_data_get(&buf);
- if(!fgets(line + strlen(line), (int)buf_chunk, stream)) /* EOF */
- break;
- }
-
- /* Remove the newline character(s) */
- last_char = strlen(line);
- while(last_char-- && (line[last_char]=='\n' || line[last_char]=='\r'));
- line[last_char + 1] = '\0';
-
- if(RES_OK != (res = parse_obj_line(obj, line)))
- goto error;
- ++obj->iline;
- }
- flush_groups(obj);
- flush_smooth_group(obj);
- flush_usemtl(obj);
exit:
- if(obj && stream)
- darray_char_release(&buf);
return res;
error:
- if(obj) AW(obj_clear(obj));
goto exit;
}
@@ -619,9 +776,9 @@ res_T
aw_obj_clear(struct aw_obj* obj)
{
if(!obj) return RES_BAD_ARG;
- darray_float_clear(&obj->positions);
- darray_float_clear(&obj->normals);
- darray_float_clear(&obj->texcoords);
+ darray_double_clear(&obj->positions);
+ darray_double_clear(&obj->normals);
+ darray_double_clear(&obj->texcoords);
darray_vertex_clear(&obj->vertices);
darray_face_clear(&obj->faces);
darray_named_group_clear(&obj->groups);
@@ -636,9 +793,9 @@ res_T
aw_obj_purge(struct aw_obj* obj)
{
if(!obj) return RES_BAD_ARG;
- darray_float_purge(&obj->positions);
- darray_float_purge(&obj->normals);
- darray_float_purge(&obj->texcoords);
+ darray_double_purge(&obj->positions);
+ darray_double_purge(&obj->normals);
+ darray_double_purge(&obj->texcoords);
darray_vertex_purge(&obj->vertices);
darray_face_purge(&obj->faces);
darray_named_group_purge(&obj->groups);
@@ -650,7 +807,7 @@ aw_obj_purge(struct aw_obj* obj)
}
res_T
-aw_obj_desc_get(struct aw_obj* obj, struct aw_obj_desc* desc)
+aw_obj_get_desc(const struct aw_obj* obj, struct aw_obj_desc* desc)
{
if(!obj || !desc)
return RES_BAD_ARG;
@@ -663,8 +820,10 @@ aw_obj_desc_get(struct aw_obj* obj, struct aw_obj_desc* desc)
}
res_T
-aw_obj_face_get
- (const struct aw_obj* obj, const size_t iface, struct aw_obj_face* face)
+aw_obj_get_face
+ (const struct aw_obj* obj,
+ const size_t iface,
+ struct aw_obj_face* face)
{
if(!obj || !face || iface >= darray_face_size_get(&obj->faces))
return RES_BAD_ARG;
@@ -673,20 +832,23 @@ aw_obj_face_get
}
res_T
-aw_obj_group_get
+aw_obj_get_group
(const struct aw_obj* obj,
const size_t igroup,
struct aw_obj_named_group* grp)
{
- const struct aw_obj_named_group* src;
+ const struct named_group* src = NULL;
if(!obj || !grp || igroup >= darray_named_group_size_get(&obj->groups))
return RES_BAD_ARG;
src = darray_named_group_cdata_get(&obj->groups) + igroup;
- return aw_obj_named_group_copy(grp, src);
+ grp->name = str_cget(&src->name);
+ grp->face_id = src->face_id;
+ grp->faces_count = src->faces_count;
+ return RES_OK;
}
res_T
-aw_obj_smooth_group_get
+aw_obj_get_smooth_group
(const struct aw_obj* obj,
const size_t ismooth_group,
struct aw_obj_smooth_group* group)
@@ -699,21 +861,26 @@ aw_obj_smooth_group_get
}
res_T
-aw_obj_mtl_get
+aw_obj_get_mtl
(const struct aw_obj* obj,
const size_t imtl,
struct aw_obj_named_group* mtl)
{
- const struct aw_obj_named_group* src;
+ const struct named_group* src;
if(!obj || !mtl || imtl >= darray_named_group_size_get(&obj->usemtls))
return RES_BAD_ARG;
src = darray_named_group_cdata_get(&obj->usemtls) + imtl;
- return aw_obj_named_group_copy(mtl, src);
+ mtl->name = str_cget(&src->name);
+ mtl->face_id = src->face_id;
+ mtl->faces_count = src->faces_count;
+ return RES_OK;
}
res_T
-aw_obj_mtllib_get
- (const struct aw_obj* obj, const size_t imtllib, const char** mtllib)
+aw_obj_get_mtllib
+ (const struct aw_obj* obj,
+ const size_t imtllib,
+ const char** mtllib)
{
const struct str* str;
if(!obj || !mtllib || imtllib >= darray_mtllib_size_get(&obj->mtllibs))
@@ -724,76 +891,82 @@ aw_obj_mtllib_get
}
res_T
-aw_obj_vertex_get
- (const struct aw_obj* obj, const size_t ivertex, struct aw_obj_vertex* vertex)
+aw_obj_get_vertex
+ (const struct aw_obj* obj,
+ const size_t ivertex,
+ struct aw_obj_vertex* vertex)
{
- const struct vertex* vert;
- const float* data;
if(!obj || !vertex || ivertex >= darray_vertex_size_get(&obj->vertices))
return RES_BAD_ARG;
- vert = darray_vertex_cdata_get(&obj->vertices) + ivertex;
+ *vertex = darray_vertex_cdata_get(&obj->vertices)[ivertex];
+ return RES_OK;
+}
+
+res_T
+aw_obj_get_vertex_data
+ (const struct aw_obj* obj,
+ const struct aw_obj_vertex* vertex,
+ struct aw_obj_vertex_data* vertex_data)
+{
+ const double* data;
+ res_T res = RES_OK;
+
+ if(!obj || !vertex || !vertex_data) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(vertex->position_id >= darray_double_size_get(&obj->positions) / 4) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(vertex->texcoord_id != VERTEX_NULL.texcoord_id
+ && vertex->texcoord_id >= darray_double_size_get(&obj->texcoords) / 3) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(vertex->normal_id != VERTEX_NULL.normal_id
+ && vertex->normal_id >= darray_double_size_get(&obj->normals) / 3) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
/* Fetch vertex position */
- ASSERT(vert->iposition != VERTEX_NULL.iposition);
- data = darray_float_cdata_get(&obj->positions) + vert->iposition * 4;
- f4_set(vertex->position, data);
+ data = darray_double_cdata_get(&obj->positions) + vertex->position_id * 4;
+ vertex_data->position[0] = data[0];
+ vertex_data->position[1] = data[1];
+ vertex_data->position[2] = data[2];
+ vertex_data->position[3] = data[3];
+
/* Setup vertex texcoord */
- if(vert->itexcoord == VERTEX_NULL.itexcoord) {
- f3_splat(vertex->texcoord, 0.f);
+ if(vertex->texcoord_id == VERTEX_NULL.texcoord_id) {
+ vertex_data->texcoord[0] = 0;
+ vertex_data->texcoord[1] = 0;
+ vertex_data->texcoord[2] = 0;
} else {
- data = darray_float_cdata_get(&obj->texcoords) + vert->itexcoord * 3;
- f3_set(vertex->texcoord, data);
+ data = darray_double_cdata_get(&obj->texcoords) + vertex->texcoord_id * 3;
+ vertex_data->texcoord[0] = data[0];
+ vertex_data->texcoord[1] = data[1];
+ vertex_data->texcoord[2] = data[2];
}
/* Setup vertex normal */
- if(vert->inormal == VERTEX_NULL.inormal) {
- f3_splat(vertex->normal, 0.f);
+ if(vertex->normal_id == VERTEX_NULL.normal_id) {
+ vertex_data->normal[0] = 0;
+ vertex_data->normal[1] = 0;
+ vertex_data->normal[2] = 0;
} else {
- data = darray_float_cdata_get(&obj->normals) + vert->inormal * 3;
- f3_set(vertex->normal, data);
+ data = darray_double_cdata_get(&obj->normals) + vertex->normal_id * 3;
+ vertex_data->normal[0] = data[0];
+ vertex_data->normal[1] = data[1];
+ vertex_data->normal[2] = data[2];
}
- 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);
+exit:
+ return res;
+error:
+ goto exit;
}
#ifdef COMPILER_CL
#pragma warning(pop)
#endif
+
diff --git a/src/test_aw_mtl.c b/src/test_aw_mtl.c
@@ -15,7 +15,7 @@
#include "aw.h"
-#include <rsys/float3.h>
+#include <rsys/double3.h>
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
@@ -50,8 +50,8 @@ test_common(struct aw_mtl* mtl)
"bump -s 1 1 1 -o 0 0 0 -bm 1 sand.mpb";
FILE* file;
size_t nmtls;
- float tmp[3];
- struct aw_material mtr;
+ double tmp[3];
+ struct aw_material mat;
CHK(mtl != NULL);
@@ -66,101 +66,92 @@ test_common(struct aw_mtl* mtl)
CHK(aw_mtl_load(mtl, "none.mtl") == RES_IO_ERR);
CHK(aw_mtl_load(mtl, "test_mtl_common.mtl") == RES_OK);
- CHK(aw_mtl_materials_count_get(NULL, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_materials_count_get(mtl, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_materials_count_get(NULL, &nmtls) == RES_BAD_ARG);
- CHK(aw_mtl_materials_count_get(mtl, &nmtls) == RES_OK);
+ CHK(aw_mtl_get_materials_count(NULL, NULL) == RES_BAD_ARG);
+ CHK(aw_mtl_get_materials_count(mtl, NULL) == RES_BAD_ARG);
+ CHK(aw_mtl_get_materials_count(NULL, &nmtls) == RES_BAD_ARG);
+ CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
CHK(nmtls == 1);
CHK(aw_mtl_clear(NULL) == RES_BAD_ARG);
CHK(aw_mtl_clear(mtl) == RES_OK);
- CHK(aw_mtl_materials_count_get(mtl, &nmtls) == RES_OK);
+ CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
CHK(nmtls == 0);
CHK(aw_mtl_load(mtl, "test_mtl_common.mtl") == RES_OK);
- CHK(aw_material_init(NULL, NULL) == RES_BAD_ARG);
- CHK(aw_material_init(NULL, &mtr) == RES_OK);
- CHK(aw_mtl_material_get(NULL, SIZE_MAX, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_material_get(mtl, SIZE_MAX, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_material_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_material_get(mtl, 0, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_material_get(NULL, SIZE_MAX, &mtr) == RES_BAD_ARG);
- CHK(aw_mtl_material_get(mtl, SIZE_MAX, &mtr) == RES_BAD_ARG);
- CHK(aw_mtl_material_get(NULL, 0, &mtr) == RES_BAD_ARG);
- CHK(aw_mtl_material_get(mtl, 0, &mtr) == RES_OK);
-
- CHK(strcmp(str_cget(&mtr.name), "my_mtl") == 0);
- CHK(mtr.ambient.color_space == AW_COLOR_RGB);
- f3(tmp, 0.0435f, 0.0436f, 0.0437f);
- CHK(f3_eq(mtr.ambient.value, tmp) == 1);
-
- CHK(mtr.diffuse.color_space == AW_COLOR_RGB);
- f3(tmp, 0.1086f, 0.1087f, 0.1088f);
- CHK(f3_eq(mtr.diffuse.value, tmp) == 1);
-
- CHK(mtr.specular.color_space == AW_COLOR_RGB);
- f3_splat(tmp, 0.f);
- CHK(f3_eq(mtr.specular.value, tmp) == 1);
-
- CHK(mtr.transmission.color_space == AW_COLOR_XYZ);
- f3(tmp, 0.987f, 0.988f, 0.989f);
- CHK(f3_eq(mtr.transmission.value, tmp) == 1);
-
- CHK(mtr.specular_exponent == 10.f);
- CHK(mtr.refraction_index == (float)1.19713f);
- CHK(mtr.illumination_model == 6);
-
- CHK(strcmp(str_cget(&mtr.ambient_map.filename), "chrome.mpc") == 0);
- CHK(mtr.ambient_map.options_mask == 0);
- CHK(mtr.ambient_map.image_bias == 0.f);
- CHK(mtr.ambient_map.image_scale == 1.f);
- CHK(f3_eq(mtr.ambient_map.texcoord_bias, f3_splat(tmp, 0.f)) == 1);
- CHK(f3_eq(mtr.ambient_map.texcoord_scale, f3_splat(tmp, 1.f)) == 1);
- CHK(f3_eq(mtr.ambient_map.texcoord_turbulence, f3_splat(tmp, 0.f)) == 1);
-
- CHK(strcmp(str_cget(&mtr.diffuse_map.filename), "chrome.mpc") == 0);
- CHK(mtr.diffuse_map.options_mask == 0);
- CHK(mtr.diffuse_map.image_bias == 0.f);
- CHK(mtr.diffuse_map.image_scale == 1.f);
- CHK(f3_eq(mtr.diffuse_map.texcoord_bias, f3_splat(tmp, 0.f)) == 1);
- CHK(f3_eq(mtr.diffuse_map.texcoord_scale, f3_splat(tmp, 1.f)) == 1);
- CHK(f3_eq(mtr.diffuse_map.texcoord_turbulence, f3_splat(tmp, 0.f)) == 1);
-
- CHK(strcmp(str_cget(&mtr.specular_map.filename), "chrome.mpc") == 0);
- CHK(mtr.specular_map.options_mask == 0);
- CHK(mtr.specular_map.image_bias == 0.f);
- CHK(mtr.specular_map.image_scale == 1.f);
- CHK(f3_eq(mtr.specular_map.texcoord_bias, f3_splat(tmp, 0.f)) == 1);
- CHK(f3_eq(mtr.specular_map.texcoord_scale, f3_splat(tmp, 1.f)) == 1);
- CHK(f3_eq(mtr.specular_map.texcoord_turbulence, f3_splat(tmp, 0.f)) == 1);
-
- CHK(strcmp(str_cget(&mtr.specular_exponent_map.filename), "wisp.mps") == 0);
- CHK(mtr.specular_exponent_map.options_mask == 0);
- CHK(mtr.specular_exponent_map.image_bias == 0.f);
- CHK(mtr.specular_exponent_map.image_scale == 1.f);
- CHK(f3_eq(mtr.specular_exponent_map.texcoord_scale, f3_splat(tmp, 1.f)) == 1);
- CHK(f3_eq(mtr.specular_exponent_map.texcoord_bias, f3_splat(tmp, 0.f)) == 1);
- CHK(f3_eq(mtr.specular_exponent_map.texcoord_turbulence, tmp) == 1);
- CHK(mtr.specular_exponent_map.scalar == AW_MAP_CHANNEL_LUMINANCE);
-
- CHK(strcmp(str_cget(&mtr.bump_map.filename), "sand.mpb") == 0);
- CHK(mtr.bump_map.options_mask == 0);
- CHK(mtr.bump_map.image_bias == 0.f);
- CHK(mtr.bump_map.image_scale == 1.f);
- CHK(f3_eq(mtr.bump_map.texcoord_scale, f3_splat(tmp, 1.f)) == 1);
- CHK(f3_eq(mtr.bump_map.texcoord_bias, f3_splat(tmp, 0.f)) == 1);
- CHK(f3_eq(mtr.bump_map.texcoord_turbulence, tmp) == 1);
- CHK(mtr.bump_map.scalar == AW_MAP_CHANNEL_LUMINANCE);
- CHK(mtr.bump_map.bump_multiplier == 1.f);
-
- CHK(aw_material_release(NULL) == RES_BAD_ARG);
- CHK(aw_material_release(&mtr) == RES_OK);
+ CHK(aw_mtl_get_material(NULL, 0, &mat) == RES_BAD_ARG);
+ CHK(aw_mtl_get_material(mtl, SIZE_MAX, &mat) == RES_BAD_ARG);
+ CHK(aw_mtl_get_material(mtl, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_mtl_get_material(mtl, 0, &mat) == RES_OK);
+
+ CHK(!strcmp(mat.name, "my_mtl"));
+ CHK(mat.ambient.color_space == AW_COLOR_RGB);
+ d3(tmp, 0.0435, 0.0436, 0.0437);
+ CHK(d3_eq(mat.ambient.value, tmp));
+
+ CHK(mat.diffuse.color_space == AW_COLOR_RGB);
+ d3(tmp, 0.1086, 0.1087, 0.1088);
+ CHK(d3_eq(mat.diffuse.value, tmp));
+
+ CHK(mat.specular.color_space == AW_COLOR_RGB);
+ d3_splat(tmp, 0);
+ CHK(d3_eq(mat.specular.value, tmp));
+
+ CHK(mat.transmission.color_space == AW_COLOR_XYZ);
+ d3(tmp, 0.987, 0.988, 0.989);
+ CHK(d3_eq(mat.transmission.value, tmp));
+
+ CHK(mat.specular_exponent == 10.0);
+ CHK(mat.refraction_index == 1.19713);
+ CHK(mat.illumination_model == 6);
+
+ CHK(!strcmp(mat.ambient_map.filename, "chrome.mpc"));
+ CHK(mat.ambient_map.options_mask == 0);
+ CHK(mat.ambient_map.image_bias == 0.f);
+ CHK(mat.ambient_map.image_scale == 1.f);
+ CHK(d3_eq(mat.ambient_map.texcoord_bias, d3_splat(tmp, 0.0)));
+ CHK(d3_eq(mat.ambient_map.texcoord_scale, d3_splat(tmp, 1.0)));
+ CHK(d3_eq(mat.ambient_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
+
+ CHK(!strcmp(mat.diffuse_map.filename, "chrome.mpc"));
+ CHK(mat.diffuse_map.options_mask == 0);
+ CHK(mat.diffuse_map.image_bias == 0.f);
+ CHK(mat.diffuse_map.image_scale == 1.f);
+ CHK(d3_eq(mat.diffuse_map.texcoord_bias, d3_splat(tmp, 0.0)));
+ CHK(d3_eq(mat.diffuse_map.texcoord_scale, d3_splat(tmp, 1.0)));
+ CHK(d3_eq(mat.diffuse_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
+
+ CHK(!strcmp(mat.specular_map.filename, "chrome.mpc"));
+ CHK(mat.specular_map.options_mask == 0);
+ CHK(mat.specular_map.image_bias == 0.0);
+ CHK(mat.specular_map.image_scale == 1.0);
+ CHK(d3_eq(mat.specular_map.texcoord_bias, d3_splat(tmp, 0.0)));
+ CHK(d3_eq(mat.specular_map.texcoord_scale, d3_splat(tmp, 1.0)));
+ CHK(d3_eq(mat.specular_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
+
+ CHK(!strcmp(mat.specular_exponent_map.filename, "wisp.mps"));
+ CHK(mat.specular_exponent_map.options_mask == 0);
+ CHK(mat.specular_exponent_map.image_bias == 0.0);
+ CHK(mat.specular_exponent_map.image_scale == 1.0);
+ CHK(d3_eq(mat.specular_exponent_map.texcoord_scale, d3_splat(tmp, 1.0)));
+ CHK(d3_eq(mat.specular_exponent_map.texcoord_bias, d3_splat(tmp, 0.0)));
+ CHK(d3_eq(mat.specular_exponent_map.texcoord_turbulence, tmp) == 1);
+ CHK(mat.specular_exponent_map.scalar == AW_MAP_CHANNEL_LUMINANCE);
+
+ CHK(!strcmp(mat.bump_map.filename, "sand.mpb"));
+ CHK(mat.bump_map.options_mask == 0);
+ CHK(mat.bump_map.image_bias == 0.0);
+ CHK(mat.bump_map.image_scale == 1.0);
+ CHK(d3_eq(mat.bump_map.texcoord_scale, d3_splat(tmp, 1.0)));
+ CHK(d3_eq(mat.bump_map.texcoord_bias, d3_splat(tmp, 0.0)));
+ CHK(d3_eq(mat.bump_map.texcoord_turbulence, tmp) == 1);
+ CHK(mat.bump_map.scalar == AW_MAP_CHANNEL_LUMINANCE);
+ CHK(mat.bump_map.bump_multiplier == 1.0);
CHK(aw_mtl_purge(NULL) == RES_BAD_ARG);
CHK(aw_mtl_purge(mtl) == RES_OK);
- CHK(aw_mtl_materials_count_get(mtl, &nmtls) == RES_OK);
+ CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
CHK(nmtls == 0);
}
@@ -205,8 +196,8 @@ test_multiple_materials(struct aw_mtl* mtl)
"Ks 2\n";
FILE* file;
size_t nmtls;
- float tmp[3];
- struct aw_material mtr;
+ double tmp[3];
+ struct aw_material mat;
CHK(mtl != NULL);
@@ -215,81 +206,78 @@ test_multiple_materials(struct aw_mtl* mtl)
fwrite(mtl_multi, sizeof(char), strlen(mtl_multi), file);
CHK(fseek(file, 0, SEEK_SET) == 0);
- CHK(aw_mtl_load_stream(NULL, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_load_stream(mtl, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_load_stream(NULL, file) == RES_BAD_ARG);
- CHK(aw_mtl_load_stream(mtl, file) == RES_OK);
- CHK(aw_mtl_materials_count_get(mtl, &nmtls) == RES_OK);
+ CHK(aw_mtl_load_stream(NULL, file, NULL) == RES_BAD_ARG);
+ CHK(aw_mtl_load_stream(mtl, NULL, NULL) == RES_BAD_ARG);
+ CHK(aw_mtl_load_stream(mtl, file, NULL) == RES_OK);
+ CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
CHK(nmtls == 3);
- CHK(aw_material_init(NULL, &mtr) == RES_OK);
- CHK(aw_mtl_material_get(mtl, 0, &mtr) == RES_OK);
- CHK(strcmp(str_cget(&mtr.name), "material_0") == 0);
- CHK(mtr.specular_exponent == 8.f);
- CHK(mtr.refraction_index == 1.5f);
- CHK(mtr.transmission.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.transmission.value, f3_splat(tmp, 1.f)) == 1);
- CHK(mtr.illumination_model == 2);
- CHK(mtr.ambient.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.ambient.value, f3_splat(tmp, 0.f)) == 1);
- CHK(mtr.diffuse.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.diffuse.value, f3(tmp, 0.734118f, 0.730588f, 0.674118f)) == 1);
- CHK(mtr.specular.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.specular.value, f3_splat(tmp, 0.f)) == 1);
- CHK(strcmp
- (str_cget(&mtr.ambient_map.filename),
- "my_long_and_verbose_filename_of_a_RED_GREEN_BLUE_1024x64_image.png") == 0);
- CHK(mtr.ambient_map.options_mask == 0);
- CHK(mtr.ambient_map.image_bias == 0.f);
- CHK(mtr.ambient_map.image_scale == 1.f);
- CHK(f3_eq(mtr.ambient_map.texcoord_bias, f3_splat(tmp, 0.f)) == 1);
- CHK(f3_eq(mtr.ambient_map.texcoord_scale, f3_splat(tmp, 1.f)) == 1);
- CHK(f3_eq(mtr.ambient_map.texcoord_turbulence, f3_splat(tmp, 0.f)) == 1);
- CHK(mtr.ambient_map.resolution == 0);
- CHK(strcmp(str_cget(&mtr.diffuse_map.filename), "tp.png") == 0);
- CHK(str_len(&mtr.specular_map.filename) == 0);
- CHK(str_len(&mtr.specular_exponent_map.filename) == 0);
- CHK(str_len(&mtr.bump_map.filename) == 0);
-
- CHK(aw_mtl_material_get(mtl, 1, &mtr) == RES_OK);
- CHK(strcmp(str_cget(&mtr.name), "textured_material") == 0);
- CHK(mtr.specular_exponent == 6.f);
- CHK(mtr.refraction_index == (float)1.7f);
- CHK(mtr.transmission.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.transmission.value, f3(tmp, 1.f, 1.2f, 1.3f)) == 1);
- CHK(mtr.illumination_model == 0);
- CHK(mtr.ambient.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.ambient.value, f3_splat(tmp, 0.f)) == 1);
- CHK(mtr.diffuse.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.diffuse.value, f3(tmp, 0.734118f, 0.709412f, 0.674118f)) == 1);
- CHK(mtr.specular.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.specular.value, f3_splat(tmp, 0.f)) == 1);
- CHK(strcmp(str_cget(&mtr.ambient_map.filename), "tex6x6.png") == 0);
- CHK(strcmp(str_cget(&mtr.diffuse_map.filename), "tex6x6.png") == 0);
- CHK(strcmp(str_cget(&mtr.bump_map.filename), "tex6x6-bump.png") == 0);
- CHK(mtr.bump_map.scalar == AW_MAP_CHANNEL_RED);
- CHK(mtr.bump_map.bump_multiplier == (float)0.2f);
- CHK(str_len(&mtr.specular_exponent_map.filename) == 0);
-
- CHK(aw_mtl_material_get(mtl, 2, &mtr) == RES_OK);
- CHK(strcmp(str_cget(&mtr.name), "hello_world") == 0);
- CHK(mtr.specular_exponent == 8.f);
- CHK(mtr.refraction_index == 1.5f);
- CHK(mtr.transmission.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.transmission.value, f3_splat(tmp, 1.f)) == 1);
- CHK(mtr.illumination_model == 2);
- CHK(mtr.ambient.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.ambient.value, f3_splat(tmp, 0.f)) == 1);
- CHK(mtr.diffuse.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.diffuse.value, f3(tmp, 0.546274f, 0.219608f, 0.183922f)) == 1);
- CHK(mtr.specular.color_space == AW_COLOR_RGB);
- CHK(f3_eq(mtr.specular.value, f3_splat(tmp, 2.f)) == 1);
- CHK(str_len(&mtr.ambient_map.filename) == 0);
- CHK(str_len(&mtr.diffuse_map.filename) == 0);
- CHK(str_len(&mtr.bump_map.filename) == 0);
- CHK(str_len(&mtr.specular_exponent_map.filename) == 0);
-
- CHK(aw_material_release(&mtr) == RES_OK);
+ CHK(aw_mtl_get_material(mtl, 0, &mat) == RES_OK);
+ CHK(!strcmp(mat.name, "material_0"));
+ CHK(mat.specular_exponent == 8.f);
+ CHK(mat.refraction_index == 1.5f);
+ CHK(mat.transmission.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.transmission.value, d3_splat(tmp, 1.0)));
+ CHK(mat.illumination_model == 2);
+ CHK(mat.ambient.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.ambient.value, d3_splat(tmp, 0.0)));
+ CHK(mat.diffuse.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.diffuse.value, d3(tmp, 0.734118, 0.730588, 0.674118)));
+ CHK(mat.specular.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.specular.value, d3_splat(tmp, 0.0)));
+ CHK(!strcmp
+ (mat.ambient_map.filename,
+ "my_long_and_verbose_filename_of_a_RED_GREEN_BLUE_1024x64_image.png"));
+ CHK(mat.ambient_map.options_mask == 0);
+ CHK(mat.ambient_map.image_bias == 0.0);
+ CHK(mat.ambient_map.image_scale == 1.0);
+ CHK(d3_eq(mat.ambient_map.texcoord_bias, d3_splat(tmp, 0.0)));
+ CHK(d3_eq(mat.ambient_map.texcoord_scale, d3_splat(tmp, 1.0)));
+ CHK(d3_eq(mat.ambient_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
+ CHK(mat.ambient_map.resolution == 0);
+ CHK(!strcmp(mat.diffuse_map.filename, "tp.png"));
+ CHK(!mat.specular_map.filename);
+ CHK(!mat.specular_exponent_map.filename);
+ CHK(!mat.bump_map.filename);
+
+ CHK(aw_mtl_get_material(mtl, 1, &mat) == RES_OK);
+ CHK(!strcmp(mat.name, "textured_material"));
+ CHK(mat.specular_exponent == 6.0);
+ CHK(mat.refraction_index == 1.7);
+ CHK(mat.transmission.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.transmission.value, d3(tmp, 1.0, 1.2, 1.3)));
+ CHK(mat.illumination_model == 0);
+ CHK(mat.ambient.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.ambient.value, d3_splat(tmp, 0.0)));
+ CHK(mat.diffuse.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.diffuse.value, d3(tmp, 0.734118, 0.709412, 0.674118)));
+ CHK(mat.specular.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.specular.value, d3_splat(tmp, 0.0)));
+ CHK(!strcmp(mat.ambient_map.filename, "tex6x6.png"));
+ CHK(!strcmp(mat.diffuse_map.filename, "tex6x6.png"));
+ CHK(!strcmp(mat.bump_map.filename, "tex6x6-bump.png"));
+ CHK(mat.bump_map.scalar == AW_MAP_CHANNEL_RED);
+ CHK(mat.bump_map.bump_multiplier == 0.2);
+ CHK(!mat.specular_exponent_map.filename);
+
+ CHK(aw_mtl_get_material(mtl, 2, &mat) == RES_OK);
+ CHK(!strcmp(mat.name, "hello_world"));
+ CHK(mat.specular_exponent == 8.0);
+ CHK(mat.refraction_index == 1.5);
+ CHK(mat.transmission.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.transmission.value, d3_splat(tmp, 1.0)));
+ CHK(mat.illumination_model == 2);
+ CHK(mat.ambient.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.ambient.value, d3_splat(tmp, 0.0)));
+ CHK(mat.diffuse.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.diffuse.value, d3(tmp, 0.546274, 0.219608, 0.183922)));
+ CHK(mat.specular.color_space == AW_COLOR_RGB);
+ CHK(d3_eq(mat.specular.value, d3_splat(tmp, 2.0)));
+ CHK(!mat.ambient_map.filename);
+ CHK(!mat.diffuse_map.filename);
+ CHK(!mat.bump_map.filename);
+ CHK(!mat.specular_exponent_map.filename);
+
fclose(file);
}
@@ -318,7 +306,7 @@ test_unloadable(struct aw_mtl* mtl)
fclose(file);
CHK(aw_mtl_load(mtl, "mtl0.mtl") == RES_BAD_ARG);
- CHK(aw_mtl_materials_count_get(mtl, &nmtls) == RES_OK);
+ CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
CHK(nmtls == 0);
}
int
@@ -330,9 +318,9 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHK(aw_mtl_create(NULL, NULL, 1, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_create(NULL, &allocator, 1, NULL) == RES_BAD_ARG);
- CHK(aw_mtl_create(NULL, NULL, 1, &mtl) == RES_OK);
+ CHK(aw_mtl_create(LOGGER_DEFAULT, NULL, 1, NULL) == RES_BAD_ARG);
+ CHK(aw_mtl_create(LOGGER_DEFAULT, &allocator, 1, NULL) == RES_BAD_ARG);
+ CHK(aw_mtl_create(LOGGER_DEFAULT, NULL, 1, &mtl) == RES_OK);
CHK(aw_mtl_ref_get(NULL) == RES_BAD_ARG);
CHK(aw_mtl_ref_get(mtl) == RES_OK);
@@ -340,7 +328,7 @@ main(int argc, char** argv)
CHK(aw_mtl_ref_put(mtl) == RES_OK);
CHK(aw_mtl_ref_put(mtl) == RES_OK);
- CHK(aw_mtl_create(LOGGER_DEFAULT, &allocator, 1, &mtl) == RES_OK);
+ CHK(aw_mtl_create(NULL, &allocator, 1, &mtl) == RES_OK);
test_common(mtl);
test_multiple_materials(mtl);
diff --git a/src/test_aw_obj.c b/src/test_aw_obj.c
@@ -15,8 +15,8 @@
#include "aw.h"
-#include <rsys/float3.h>
-#include <rsys/float4.h>
+#include <rsys/double3.h>
+#include <rsys/double4.h>
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
@@ -29,6 +29,7 @@ test_plane(struct aw_obj* obj)
"mtllib master.mtl"
"\n"
"g\n"
+ "o plane\n"
"v 0.0000 2.0000 0.0000\n"
"v 0.0000 0.0000 0.0000\n"
"v 2.0000 0.0000 0.0000\n"
@@ -42,12 +43,13 @@ test_plane(struct aw_obj* obj)
"usemtl wood\n"
"f 1/1 2/2 3/3 4/4\n"
"# 1 element\n";
- float v4[4];
+ double v4[4];
struct aw_obj_desc desc;
struct aw_obj_face face;
struct aw_obj_named_group group;
struct aw_obj_named_group mtl;
struct aw_obj_vertex vertex;
+ struct aw_obj_vertex_data vdata;
FILE* file;
const char* mtllib;
@@ -58,98 +60,89 @@ test_plane(struct aw_obj* obj)
fwrite(plane_obj, sizeof(char), strlen(plane_obj), file);
fclose(file);
- CHK(aw_obj_named_group_init(NULL, NULL) == RES_BAD_ARG);
- CHK(aw_obj_named_group_init(NULL, &group) == RES_OK);
- CHK(aw_obj_named_group_init(NULL, &mtl) == RES_OK);
-
- CHK(aw_obj_load(NULL, NULL) == RES_BAD_ARG);
CHK(aw_obj_load(obj, NULL) == RES_BAD_ARG);
CHK(aw_obj_load(NULL, "test_obj_plane.obj") == RES_BAD_ARG);
CHK(aw_obj_load(obj, "none.obj") == RES_IO_ERR);
CHK(aw_obj_load(obj, "test_obj_plane.obj") == RES_OK);
- CHK(aw_obj_desc_get(NULL, NULL) == RES_BAD_ARG);
- CHK(aw_obj_desc_get(obj, NULL) == RES_BAD_ARG);
- CHK(aw_obj_desc_get(NULL, &desc) == RES_BAD_ARG);
- CHK(aw_obj_desc_get(obj, &desc) == RES_OK);
+ CHK(aw_obj_get_desc(NULL, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_desc(obj, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_desc(NULL, &desc) == RES_BAD_ARG);
+ CHK(aw_obj_get_desc(obj, &desc) == RES_OK);
CHK(desc.faces_count == 1);
CHK(desc.groups_count == 1);
CHK(desc.smooth_groups_count == 0);
CHK(desc.usemtls_count == 1);
CHK(desc.mtllibs_count == 1);
- CHK(aw_obj_face_get(NULL, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_face_get(obj, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_face_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_face_get(obj, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_face_get(NULL, AW_ID_NONE, &face) == RES_BAD_ARG);
- CHK(aw_obj_face_get(obj, AW_ID_NONE, &face) == RES_BAD_ARG);
- CHK(aw_obj_face_get(NULL, 0, &face) == RES_BAD_ARG);
- CHK(aw_obj_face_get(obj, 0, &face) == RES_OK);
+ CHK(aw_obj_get_face(NULL, 0, &face) == RES_BAD_ARG);
+ CHK(aw_obj_get_face(obj, AW_ID_NONE, &face) == RES_BAD_ARG);
+ CHK(aw_obj_get_face(obj, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_face(obj, 0, &face) == RES_OK);
CHK(face.vertex_id == 0);
CHK(face.vertices_count == 4);
CHK(face.group_id == 0);
CHK(face.smooth_group_id == AW_ID_NONE);
CHK(face.mtl_id == 0);
- CHK(aw_obj_mtl_get(NULL, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtl_get(obj, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtl_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtl_get(obj, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtl_get(NULL, AW_ID_NONE, &mtl) == RES_BAD_ARG);
- CHK(aw_obj_mtl_get(obj, AW_ID_NONE, &mtl) == RES_BAD_ARG);
- CHK(aw_obj_mtl_get(NULL, 0, &mtl) == RES_BAD_ARG);
- CHK(aw_obj_mtl_get(obj, 0, &mtl) == RES_OK);
- CHK(strcmp(str_cget(&mtl.name), "wood") == 0);
+ CHK(aw_obj_get_mtl(NULL, 0, &mtl) == RES_BAD_ARG);
+ CHK(aw_obj_get_mtl(obj, AW_ID_NONE, &mtl) == RES_BAD_ARG);
+ CHK(aw_obj_get_mtl(obj, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_mtl(obj, 0, &mtl) == RES_OK);
+ CHK(!strcmp(mtl.name, "wood"));
CHK(mtl.face_id == 0);
CHK(mtl.faces_count == 1);
- CHK(aw_obj_mtllib_get(NULL, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtllib_get(obj, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtllib_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtllib_get(obj, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_mtllib_get(NULL, AW_ID_NONE, &mtllib) == RES_BAD_ARG);
- CHK(aw_obj_mtllib_get(obj, AW_ID_NONE, &mtllib) == RES_BAD_ARG);
- CHK(aw_obj_mtllib_get(NULL, 0, &mtllib) == RES_BAD_ARG);
- CHK(aw_obj_mtllib_get(obj, 0, &mtllib) == RES_OK);
+ CHK(aw_obj_get_mtllib(NULL, 0, &mtllib) == RES_BAD_ARG);
+ CHK(aw_obj_get_mtllib(obj, AW_ID_NONE, &mtllib) == RES_BAD_ARG);
+ CHK(aw_obj_get_mtllib(obj, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_mtllib(obj, 0, &mtllib) == RES_OK);
CHK(strcmp(mtllib, "master.mtl") == 0);
- CHK(aw_obj_vertex_get(NULL, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_vertex_get(obj, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_vertex_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_vertex_get(obj, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_vertex_get(NULL, AW_ID_NONE, &vertex) == RES_BAD_ARG);
- CHK(aw_obj_vertex_get(obj, AW_ID_NONE, &vertex) == RES_BAD_ARG);
- CHK(aw_obj_vertex_get(NULL, 0, &vertex) == RES_BAD_ARG);
-
- CHK(aw_obj_vertex_get(obj, 0, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 0.f, 2.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.texcoord, f3(v4, 0.f, 1.f, 0.f)) == 1);
- CHK(aw_obj_vertex_get(obj, 1, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 0.f, 0.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.texcoord, f3(v4, 0.f, 0.f, 0.f)) == 1);
- CHK(aw_obj_vertex_get(obj, 2, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 2.f, 0.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.texcoord, f3(v4, 1.f, 0.f, 0.f)) == 1);
- CHK(aw_obj_vertex_get(obj, 3, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 2.f, 2.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.texcoord, f3(v4, 1.f, 1.f, 0.f)) == 1);
-
- CHK(aw_obj_group_get(NULL, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(NULL, AW_ID_NONE, &group) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, AW_ID_NONE, &group) == RES_BAD_ARG);
- CHK(aw_obj_group_get(NULL, 0, &group) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, 0, &group) == RES_OK);
- CHK(strcmp(str_cget(&group.name), "default") == 0);
+ CHK(aw_obj_get_vertex(NULL, 0, &vertex) == RES_BAD_ARG);
+ CHK(aw_obj_get_vertex(obj, AW_ID_NONE, &vertex) == RES_BAD_ARG);
+ CHK(aw_obj_get_vertex(obj, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_vertex(obj, 0, &vertex) == RES_OK);
+
+ CHK(aw_obj_get_vertex_data(NULL, &vertex, &vdata) == RES_BAD_ARG);
+ CHK(aw_obj_get_vertex_data(obj, NULL, &vdata) == RES_BAD_ARG);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, NULL) == RES_BAD_ARG);
+
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 0, 2, 0, 1)));
+ CHK(d3_eq(vdata.texcoord, d3(v4, 0, 1, 0)));
+
+ vertex.position_id = 4;
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_BAD_ARG);
+ vertex.position_id = 0;
+ vertex.texcoord_id = 4;
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_BAD_ARG);
+ vertex.texcoord_id = 0;
+ vertex.normal_id = 0;
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_BAD_ARG);
+
+ CHK(aw_obj_get_vertex(obj, 1, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 0, 0, 0, 1)));
+ CHK(d3_eq(vdata.texcoord, d3(v4, 0, 0, 0)));
+
+ CHK(aw_obj_get_vertex(obj, 2, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 2, 0, 0, 1)));
+ CHK(d3_eq(vdata.texcoord, d3(v4, 1, 0, 0)));
+
+ CHK(aw_obj_get_vertex(obj, 3, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 2, 2, 0, 1)));
+ CHK(d3_eq(vdata.texcoord, d3(v4, 1, 1, 0)));
+
+ CHK(aw_obj_get_group(NULL, 0, &group) == RES_BAD_ARG);
+ CHK(aw_obj_get_group(obj, AW_ID_NONE, &group) == RES_BAD_ARG);
+ CHK(aw_obj_get_group(obj, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_group(obj, 0, &group) == RES_OK);
+ CHK(!strcmp(group.name, "default"));
CHK(group.face_id == 0);
CHK(group.faces_count == 1);
-
- CHK(aw_obj_named_group_release(NULL) == RES_BAD_ARG);
- CHK(aw_obj_named_group_release(&group) == RES_OK);
- CHK(aw_obj_named_group_release(&mtl) == RES_OK);
}
static void
@@ -177,18 +170,17 @@ test_squares(struct aw_obj* obj)
"f 1//1 2//2 3//3 4//4\n"
"f 4//4 3//3 5//5 6//6\n"
"# 2 elements\n";
- float v4[4];
+ double v4[4];
struct aw_obj_desc desc;
struct aw_obj_face face;
struct aw_obj_named_group group;
struct aw_obj_named_group mtl;
struct aw_obj_smooth_group sgroup;
struct aw_obj_vertex vertex;
+ struct aw_obj_vertex_data vdata;
FILE* file;
CHK(obj != NULL);
- CHK(aw_obj_named_group_init(NULL, &group) == RES_OK);
- CHK(aw_obj_named_group_init(NULL, &mtl) == RES_OK);
file = fopen("test_obj_squares.obj", "w");
CHK(file != NULL);
@@ -196,81 +188,78 @@ test_squares(struct aw_obj* obj)
fclose(file);
CHK(aw_obj_load(obj, "test_obj_squares.obj") == RES_OK);
- CHK(aw_obj_desc_get(obj, &desc) == RES_OK);
+ CHK(aw_obj_get_desc(obj, &desc) == RES_OK);
CHK(desc.faces_count == 2);
CHK(desc.groups_count == 1);
CHK(desc.smooth_groups_count == 1);
CHK(desc.usemtls_count == 0);
CHK(desc.mtllibs_count == 0);
- CHK(aw_obj_face_get(obj, 0, &face) == RES_OK);
+ CHK(aw_obj_get_face(obj, 0, &face) == RES_OK);
CHK(face.vertex_id == 0);
CHK(face.vertices_count == 4);
CHK(face.group_id == 0);
CHK(face.smooth_group_id == 0);
CHK(face.mtl_id == AW_ID_NONE);
- CHK(aw_obj_vertex_get(obj, 0, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 0.f, 2.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.f, 0.f, 1.f)) == 1);
- CHK(aw_obj_vertex_get(obj, 1, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 0.f, 0.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.f, 0.f, 1.f)) == 1);
- CHK(aw_obj_vertex_get(obj, 2, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 2.f, 0.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.276597f, 0.f, 0.960986f)) == 1);
- CHK(aw_obj_vertex_get(obj, 3, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 2.f, 2.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.276597f, 0.f, 0.960986f)) == 1);
-
- CHK(aw_obj_face_get(obj, 1, &face) == RES_OK);
+ CHK(aw_obj_get_vertex(obj, 0, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 0.0, 2.0, 0.0, 1.0)));
+ CHK(d3_eq(vdata.normal, d3(v4, 0.0, 0.0, 1.0)));
+ CHK(aw_obj_get_vertex(obj, 1, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 0.0, 0.0, 0.0, 1.0)));
+ CHK(d3_eq(vdata.normal, d3(v4, 0.0, 0.0, 1.0)));
+ CHK(aw_obj_get_vertex(obj, 2, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 2.0, 0.0, 0.0, 1.0)));
+ CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986)));
+ CHK(aw_obj_get_vertex(obj, 3, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 2.0, 2.0, 0.0, 1.0)));
+ CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986)));
+
+ CHK(aw_obj_get_face(obj, 1, &face) == RES_OK);
CHK(face.vertex_id == 4);
CHK(face.vertices_count == 4);
CHK(face.group_id == 0);
CHK(face.smooth_group_id == 0);
CHK(face.mtl_id == AW_ID_NONE);
- CHK(aw_obj_vertex_get(obj, 4, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 2.f, 2.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.276597f, 0.f, 0.960986f)) == 1);
- CHK(aw_obj_vertex_get(obj, 5, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 2.f, 0.f, 0.f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.276597f, 0.f, 0.960986f)) == 1);
- CHK(aw_obj_vertex_get(obj, 6, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 4.f, 0.f, -1.255298f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.531611f, 0.f, 0.846988f)) == 1);
- CHK(aw_obj_vertex_get(obj, 7, &vertex) == RES_OK);
- CHK(f4_eq(vertex.position, f4(v4, 4.f, 2.f, -1.255298f, 1.f)) == 1);
- CHK(f3_eq(vertex.normal, f3(v4, 0.531611f, 0.f, 0.846988f)) == 1);
-
- CHK(aw_obj_group_get(NULL, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_group_get(NULL, AW_ID_NONE, &group) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, AW_ID_NONE, &group) == RES_BAD_ARG);
- CHK(aw_obj_group_get(NULL, 0, &group) == RES_BAD_ARG);
- CHK(aw_obj_group_get(obj, 0, &group) == RES_OK);
- CHK(strcmp(str_cget(&group.name), "all") == 0);
+ CHK(aw_obj_get_vertex(obj, 4, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 2.0, 2.0, 0.0, 1.0)));
+ CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986)));
+ CHK(aw_obj_get_vertex(obj, 5, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 2.0, 0.0, 0.0, 1.0)));
+ CHK(d3_eq(vdata.normal, d3(v4, 0.276597, 0.0, 0.960986)));
+ CHK(aw_obj_get_vertex(obj, 6, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 4.0, 0.0, -1.255298, 1.0)));
+ CHK(d3_eq(vdata.normal, d3(v4, 0.531611, 0.0, 0.8469880)));
+ CHK(aw_obj_get_vertex(obj, 7, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d4_eq(vdata.position, d4(v4, 4.0, 2.0, -1.255298, 1.0)) == 1);
+ CHK(d3_eq(vdata.normal, d3(v4, 0.531611, 0.0, 0.846988)) == 1);
+
+ CHK(aw_obj_get_group(NULL, 0, &group) == RES_BAD_ARG);
+ CHK(aw_obj_get_group(obj, AW_ID_NONE, &group) == RES_BAD_ARG);
+ CHK(aw_obj_get_group(obj, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_group(obj, 0, &group) == RES_OK);
+ CHK(strcmp(group.name, "all") == 0);
CHK(group.face_id == 0);
CHK(group.faces_count == 2);
- CHK(aw_obj_smooth_group_get(NULL, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_smooth_group_get(obj, AW_ID_NONE, NULL) == RES_BAD_ARG);
- CHK(aw_obj_smooth_group_get(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_smooth_group_get(obj, 0, NULL) == RES_BAD_ARG);
- CHK(aw_obj_smooth_group_get(NULL, AW_ID_NONE, &sgroup) == RES_BAD_ARG);
- CHK(aw_obj_smooth_group_get(obj, AW_ID_NONE, &sgroup) == RES_BAD_ARG);
- CHK(aw_obj_smooth_group_get(NULL, 0, &sgroup) == RES_BAD_ARG);
- CHK(aw_obj_smooth_group_get(obj, 0, &sgroup) == RES_OK);
+ CHK(aw_obj_get_smooth_group(NULL, 0, &sgroup) == RES_BAD_ARG);
+ CHK(aw_obj_get_smooth_group(obj, AW_ID_NONE, &sgroup) == RES_BAD_ARG);
+ CHK(aw_obj_get_smooth_group(obj, 0, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_get_smooth_group(obj, 0, &sgroup) == RES_OK);
CHK(sgroup.is_smoothed == 1);
CHK(sgroup.face_id == 0);
CHK(sgroup.faces_count == 2);
- CHK(aw_obj_mtl_get(obj, 0, &mtl) == RES_BAD_ARG);
-
- CHK(aw_obj_named_group_release(&group) == RES_OK);
- CHK(aw_obj_named_group_release(&mtl) == RES_OK);
+ CHK(aw_obj_get_mtl(obj, 0, &mtl) == RES_BAD_ARG);
}
static void
@@ -324,12 +313,11 @@ test_cube(struct aw_obj* obj)
fwrite(cube_obj, sizeof(char), strlen(cube_obj), file);
CHK(fseek(file, 0, SEEK_SET) == 0);
- CHK(aw_obj_load_stream(NULL, NULL) == RES_BAD_ARG);
- CHK(aw_obj_load_stream(obj, NULL) == RES_BAD_ARG);
- CHK(aw_obj_load_stream(NULL, file) == RES_BAD_ARG);
- CHK(aw_obj_load_stream(obj, file) == RES_OK);
+ CHK(aw_obj_load_stream(obj, NULL, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_load_stream(NULL, file, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_load_stream(obj, file, NULL) == RES_OK);
- CHK(aw_obj_desc_get(obj, &desc) == RES_OK);
+ CHK(aw_obj_get_desc(obj, &desc) == RES_OK);
CHK(desc.faces_count == 6);
CHK(desc.groups_count == 6);
CHK(desc.smooth_groups_count == 0);
@@ -338,7 +326,7 @@ test_cube(struct aw_obj* obj)
CHK(aw_obj_clear(NULL) == RES_BAD_ARG);
CHK(aw_obj_clear(obj) == RES_OK);
- CHK(aw_obj_desc_get(obj, &desc) == RES_OK);
+ CHK(aw_obj_get_desc(obj, &desc) == RES_OK);
CHK(desc.faces_count == 0);
CHK(desc.groups_count == 0);
CHK(desc.smooth_groups_count == 0);
@@ -346,12 +334,12 @@ test_cube(struct aw_obj* obj)
CHK(desc.mtllibs_count == 0);
CHK(fseek(file, 0, SEEK_SET) == 0);
- CHK(aw_obj_load_stream(obj, file) == RES_OK);
- CHK(aw_obj_desc_get(obj, &desc) == RES_OK);
+ CHK(aw_obj_load_stream(obj, file, "cube") == RES_OK);
+ CHK(aw_obj_get_desc(obj, &desc) == RES_OK);
FOR_EACH(i, 0, 6) {
struct aw_obj_face face;
- CHK(aw_obj_face_get(obj, i, &face) == RES_OK);
+ CHK(aw_obj_get_face(obj, i, &face) == RES_OK);
CHK(face.vertex_id == i*4);
CHK(face.vertices_count == 4);
CHK(face.group_id == i);
@@ -361,35 +349,31 @@ test_cube(struct aw_obj* obj)
FOR_EACH(i, 0, 6) {
struct aw_obj_named_group group;
- CHK(aw_obj_named_group_init(NULL, &group) == RES_OK);
- CHK(aw_obj_group_get(obj, i, &group) == RES_OK);
- CHK(strcmp(str_cget(&group.name), group_names[i]) == 0);
+ CHK(aw_obj_get_group(obj, i, &group) == RES_OK);
+ CHK(!strcmp(group.name, group_names[i]));
CHK(group.face_id == i);
CHK(group.faces_count == 1);
- CHK(aw_obj_named_group_release(&group) == RES_OK);
}
FOR_EACH(i, 0, 6) {
struct aw_obj_named_group mtl;
- CHK(aw_obj_named_group_init(NULL, &mtl) == RES_OK);
- CHK(aw_obj_mtl_get(obj, i, &mtl) == RES_OK);
- CHK(strcmp(str_cget(&mtl.name), mtl_names[i]) == 0);
+ CHK(aw_obj_get_mtl(obj, i, &mtl) == RES_OK);
+ CHK(!strcmp(mtl.name, mtl_names[i]));
CHK(mtl.face_id == i);
CHK(mtl.faces_count == 1);
- CHK(aw_obj_named_group_release(&mtl) == RES_OK);
}
- CHK(aw_obj_mtllib_get(obj, 0, &mtllib) == RES_OK);
- CHK(strcmp(mtllib, "master.mtl") == 0);
- CHK(aw_obj_mtllib_get(obj, 1, &mtllib) == RES_OK);
- CHK(strcmp(mtllib, "hop.mtl") == 0);
- CHK(aw_obj_mtllib_get(obj, 2, &mtllib) == RES_OK);
- CHK(strcmp(mtllib, "my.mtl") == 0);
- CHK(aw_obj_mtllib_get(obj, 3, &mtllib) == RES_BAD_ARG);
+ CHK(aw_obj_get_mtllib(obj, 0, &mtllib) == RES_OK);
+ CHK(!strcmp(mtllib, "master.mtl"));
+ CHK(aw_obj_get_mtllib(obj, 1, &mtllib) == RES_OK);
+ CHK(!strcmp(mtllib, "hop.mtl"));
+ CHK(aw_obj_get_mtllib(obj, 2, &mtllib) == RES_OK);
+ CHK(!strcmp(mtllib, "my.mtl"));
+ CHK(aw_obj_get_mtllib(obj, 3, &mtllib) == RES_BAD_ARG);
CHK(aw_obj_purge(NULL) == RES_BAD_ARG);
CHK(aw_obj_purge(obj) == RES_OK);
- CHK(aw_obj_desc_get(obj, &desc) == RES_OK);
+ CHK(aw_obj_get_desc(obj, &desc) == RES_OK);
CHK(desc.faces_count == 0);
CHK(desc.groups_count == 0);
CHK(desc.smooth_groups_count == 0);
@@ -446,106 +430,114 @@ test_cbox(struct aw_obj* obj)
struct aw_obj_desc desc;
struct aw_obj_face face;
struct aw_obj_vertex vertex;
+ struct aw_obj_vertex_data vdata;
struct aw_obj_named_group group;
struct aw_obj_named_group mtl;
- float tmp[3];
+ double tmp[3];
FILE* file;
CHK(obj != NULL);
- CHK(aw_obj_named_group_init(NULL, &group) == RES_OK);
- CHK(aw_obj_named_group_init(NULL, &mtl) == RES_OK);
file = fopen("test_cbox.obj", "w+");
CHK(file != NULL);
fwrite(cbox_obj, sizeof(char), strlen(cbox_obj), file);
CHK(fseek(file, 0, SEEK_SET) == 0);
- CHK(aw_obj_load_stream(obj, file) == RES_OK);
+ CHK(aw_obj_load_stream(obj, file, "cbox") == RES_OK);
fclose(file);
- CHK(aw_obj_desc_get(obj, &desc) == RES_OK);
+ CHK(aw_obj_get_desc(obj, &desc) == RES_OK);
CHK(desc.faces_count == 5);
CHK(desc.groups_count == 5);
CHK(desc.smooth_groups_count == 0);
CHK(desc.usemtls_count == 5);
CHK(desc.mtllibs_count == 1);
- CHK(aw_obj_face_get(obj, 0, &face) == RES_OK);
+ CHK(aw_obj_get_face(obj, 0, &face) == RES_OK);
CHK(face.vertex_id == 0);
CHK(face.vertices_count == 4);
CHK(face.group_id == 0);
CHK(face.mtl_id == 0);
- CHK(aw_obj_group_get(obj, 0, &group) == RES_OK);
- CHK(strcmp(str_cget(&group.name), "floor") == 0);
+ CHK(aw_obj_get_group(obj, 0, &group) == RES_OK);
+ CHK(!strcmp(group.name, "floor"));
CHK(group.face_id == 0);
CHK(group.faces_count == 1);
- CHK(aw_obj_mtl_get(obj, 0, &mtl) == RES_OK);
- CHK(strcmp(str_cget(&mtl.name), "floor") == 0);
+ CHK(aw_obj_get_mtl(obj, 0, &mtl) == RES_OK);
+ CHK(!strcmp(mtl.name, "floor"));
CHK(mtl.face_id == 0);
CHK(mtl.faces_count == 1);
- CHK(aw_obj_vertex_get(obj, 0, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -1.01f, 0.f, 0.99f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 1, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, 1.f, 0.f, 0.99f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 2, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, 1.f, 0.f, -1.04f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 3, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -0.99f, 0.f, -1.04f), 1.e-6f) == 1);
-
- CHK(aw_obj_face_get(obj, 1, &face) == RES_OK);
+ CHK(aw_obj_get_vertex(obj, 0, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -1.01, 0.0, 0.99), 1.e-6));
+ CHK(aw_obj_get_vertex(obj, 1, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, 1.0, 0.0, 0.99), 1.e-6));
+ CHK(aw_obj_get_vertex(obj, 2, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, 1.f, 0.0, -1.04), 1.e-6));
+ CHK(aw_obj_get_vertex(obj, 3, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -0.99, 0.0, -1.04), 1.e-6));
+
+ CHK(aw_obj_get_face(obj, 1, &face) == RES_OK);
CHK(face.vertex_id == 4);
CHK(face.vertices_count == 4);
CHK(face.group_id == 1);
CHK(face.mtl_id == 1);
- CHK(aw_obj_group_get(obj, 1, &group) == RES_OK);
- CHK(strcmp(str_cget(&group.name), "ceiling") == 0);
+ CHK(aw_obj_get_group(obj, 1, &group) == RES_OK);
+ CHK(!strcmp(group.name, "ceiling"));
CHK(group.face_id == 1);
CHK(group.faces_count == 1);
- CHK(aw_obj_mtl_get(obj, 1, &mtl) == RES_OK);
- CHK(strcmp(str_cget(&mtl.name), "ceiling") == 0);
+ CHK(aw_obj_get_mtl(obj, 1, &mtl) == RES_OK);
+ CHK(!strcmp(mtl.name, "ceiling"));
CHK(mtl.face_id == 1);
CHK(mtl.faces_count == 1);
- CHK(aw_obj_vertex_get(obj, 4, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -1.02f, 1.99f, 0.99f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 5, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -1.02f, 1.99f, -1.04f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 6, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, 1.f, 1.99f, -1.04f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 7, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, 1.f, 1.99f, 0.99f), 1.e-6f) == 1);
-
- CHK(aw_obj_face_get(obj, 4, &face) == RES_OK);
+ CHK(aw_obj_get_vertex(obj, 4, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, 0.99), 1.e-6));
+ CHK(aw_obj_get_vertex(obj, 5, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, -1.04), 1.e-6f));
+ CHK(aw_obj_get_vertex(obj, 6, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, 1.0, 1.99, -1.04), 1.e-6f));
+ CHK(aw_obj_get_vertex(obj, 7, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, 1.0, 1.99, 0.99), 1.e-6f));
+
+ CHK(aw_obj_get_face(obj, 4, &face) == RES_OK);
CHK(face.vertex_id == 16);
CHK(face.vertices_count == 4);
CHK(face.group_id == 4);
CHK(face.mtl_id == 4);
- CHK(aw_obj_group_get(obj, 4, &group) == RES_OK);
- CHK(strcmp(str_cget(&group.name), "left") == 0);
+ CHK(aw_obj_get_group(obj, 4, &group) == RES_OK);
+ CHK(!strcmp(group.name, "left"));
CHK(group.face_id == 4);
CHK(group.faces_count == 1);
- CHK(aw_obj_mtl_get(obj, 4, &mtl) == RES_OK);
- CHK(strcmp(str_cget(&mtl.name), "left") == 0);
+ CHK(aw_obj_get_mtl(obj, 4, &mtl) == RES_OK);
+ CHK(!strcmp(mtl.name, "left"));
CHK(mtl.face_id == 4);
CHK(mtl.faces_count == 1);
- CHK(aw_obj_vertex_get(obj, 16, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -1.01f, 0.f, 0.99f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 17, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -0.99f, 0.f, -1.04f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 18, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -1.02f, 1.99f, -1.04f), 1.e-6f) == 1);
- CHK(aw_obj_vertex_get(obj, 19, &vertex) == RES_OK);
- CHK(f3_eq_eps(vertex.position, f3(tmp, -1.02f, 1.99f, 0.99f), 1.e-6f) == 1);
-
- CHK(aw_obj_named_group_release(&group) == RES_OK);
- CHK(aw_obj_named_group_release(&mtl) == RES_OK);
+ CHK(aw_obj_get_vertex(obj, 16, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -1.01, 0.0, 0.99), 1.e-6));
+ CHK(aw_obj_get_vertex(obj, 17, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -0.99, 0.0, -1.04), 1.e-6));
+ CHK(aw_obj_get_vertex(obj, 18, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, -1.04), 1.e-6));
+ CHK(aw_obj_get_vertex(obj, 19, &vertex) == RES_OK);
+ CHK(aw_obj_get_vertex_data(obj, &vertex, &vdata) == RES_OK);
+ CHK(d3_eq_eps(vdata.position, d3(tmp, -1.02, 1.99, 0.99), 1.e-6));
}
int
@@ -557,9 +549,9 @@ main(int argc, char** argv)
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHK(aw_obj_create(NULL, NULL, 1, NULL) == RES_BAD_ARG);
- CHK(aw_obj_create(NULL, &allocator, 1, NULL) == RES_BAD_ARG);
- CHK(aw_obj_create(NULL, NULL, 1, &obj) == RES_OK);
+ CHK(aw_obj_create(LOGGER_DEFAULT, NULL, 1, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_create(LOGGER_DEFAULT, &allocator, 1, NULL) == RES_BAD_ARG);
+ CHK(aw_obj_create(LOGGER_DEFAULT, NULL, 1, &obj) == RES_OK);
CHK(aw_obj_ref_get(NULL) == RES_BAD_ARG);
CHK(aw_obj_ref_get(obj) == RES_OK);
@@ -567,7 +559,7 @@ main(int argc, char** argv)
CHK(aw_obj_ref_put(obj) == RES_OK);
CHK(aw_obj_ref_put(obj) == RES_OK);
- CHK(aw_obj_create(LOGGER_DEFAULT, &allocator, 1, &obj) == RES_OK);
+ CHK(aw_obj_create(NULL, &allocator, 1, &obj) == RES_OK);
test_plane(obj);
test_squares(obj);