loader_aw

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

commit 9c19d9a02bf07a4248d90e6ffa6cb19b9f1df4f7
parent d5420267859cf3bc068a1aa3bd81ebb5c928fab4
Author: vaplv <vaplv@free.fr>
Date:   Sat, 12 Jul 2014 11:52:16 +0200

Begin to parse the map_XX directive

Diffstat:
Msrc/aw_mtl.c | 216+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 200 insertions(+), 16 deletions(-)

diff --git a/src/aw_mtl.c b/src/aw_mtl.c @@ -10,9 +10,12 @@ #include <float.h> +/******************************************************************************* + * Color helper data structure + ******************************************************************************/ struct color { float value[3]; - char is_CIEXYZ; + char is_CIEXYZ; /* Define if value is encoded in the CIE XYZ color space */ }; static FINLINE void @@ -23,6 +26,85 @@ color_copy(struct color* dst, const struct color* src) dst->is_CIEXYZ = src->is_CIEXYZ; } +/******************************************************************************* + * Map helper data structure + ******************************************************************************/ +enum map_flag { + MAP_BLEND_U = BIT(0), + MAP_BLEND_V = BIT(1), + MAP_COLOR_CORRECTION = BIT(2), + MAP_CLAMP = BIT(3) +}; + +enum map_channel { + MAP_CHANNEL_RED, + MAP_CHANNEL_GREEN, + MAP_CHANNEL_BLUE, + MAP_CHANNEL_MATTE, + MAP_CHANNEL_LUMINANCE, + MAP_CHANNEL_DEPTH +}; + +struct map { + struct str filename; + int mask_options; /* Combination of map_flag */ + enum map_channel channel; /* Channel used to create a scalar/bump texture */ + float texture_bias; /* Scalar to add to the image */ + float texture_scale; /* Scale to multiply to the image */ + float origin[3]; /* Texcoord offset */ + float scale[3]; /* Texcoord scale */ + float turbulence[3]; /* Texcoord turbulence */ + size_t resolution; +}; + +static FINLINE void +map_init(struct mem_allocator* allocator, struct map* map) +{ + ASSERT(map); + memset(map, 0, sizeof(struct map)); + str_init(allocator, &map->filename); +} + +static FINLINE void +map_release(struct map* map) +{ + ASSERT(map); + str_release(&map->filename); +} + +static FINLINE void +map_copy_pod__(struct map* dst, const struct map* src) +{ + ASSERT(dst && src); + dst->mask_options = src->mask_options; + dst->channel = src->channel; + dst->texture_bias = src->texture_bias; + dst->texture_scale = src->texture_scale; + f3_set(dst->origin, src->origin); + f3_set(dst->scale, src->scale); + f3_set(dst->turbulence, src->turbulence); + dst->resolution = src->resolution; +} + +static FINLINE int +map_copy(struct map* dst, const struct map* src) +{ + ASSERT(dst && src); + map_copy_pod__(dst, src); + return str_copy(&dst->filename, &src->filename); +} + +static FINLINE int +map_copy_and_release(struct map* dst, struct map* src) +{ + ASSERT(dst && src); + map_copy_pod__(dst, src); + return str_copy_and_release(&dst->filename, &src->filename); +} + +/******************************************************************************* + * Material helper data structure + ******************************************************************************/ struct material { struct str name; struct color ambient; @@ -32,6 +114,11 @@ struct material { float specular_exp; float refraction_id; size_t illumination; /* Illumination model identifier */ + struct map ambient_map; + struct map diffuse_map; + struct map specular_map; + struct map specular_exp_map; + struct map bump_map; }; static FINLINE void @@ -39,6 +126,11 @@ material_init(struct mem_allocator* allocator, struct material* mtl) { ASSERT(mtl); 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_exp_map); + map_init(allocator, &mtl->bump_map); } static FINLINE void @@ -46,10 +138,15 @@ 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_exp_map); + map_release(&mtl->bump_map); } -static FINLINE int -material_copy(struct material* dst, const struct material* src) +static FINLINE void +material_copy_pod__(struct material* dst, const struct material* src) { ASSERT(dst && src); color_copy(&dst->ambient, &src->ambient); @@ -59,23 +156,49 @@ material_copy(struct material* dst, const struct material* src) dst->specular_exp = src->specular_exp; dst->refraction_id = src->refraction_id; dst->illumination = src->illumination; - return str_copy(&dst->name, &src->name); +} + +static FINLINE int +material_copy(struct material* dst, const struct material* src) +{ + material_copy_pod__(dst, src); + if(map_copy(&dst->ambient_map, &src->ambient_map)) + return -1; + if(map_copy(&dst->diffuse_map, &src->diffuse_map)) + return -1; + if(map_copy(&dst->specular_map, &src->specular_map)) + return -1; + if(map_copy(&dst->specular_exp_map, &src->specular_exp_map)) + return -1; + if(map_copy(&dst->bump_map, &src->bump_map)) + return -1; + if(str_copy(&dst->name, &src->name)) + return -1; } static FINLINE int material_copy_and_release(struct material* dst, struct material* src) { ASSERT(dst && src); - color_copy(&dst->ambient, &src->ambient); - color_copy(&dst->diffuse, &src->diffuse); - color_copy(&dst->specular, &src->specular); - color_copy(&dst->transmission, &src->transmission); - dst->specular_exp = src->specular_exp; - dst->refraction_id = src->refraction_id; - dst->illumination = src->illumination; - return str_copy_and_release(&dst->name, &src->name); + material_copy_pod__(dst, src); + if(map_copy_and_release(&dst->ambient_map, &src->ambient_map)) + return -1; + if(map_copy_and_release(&dst->diffuse_map, &src->diffuse_map)) + return -1; + if(map_copy_and_release(&dst->specular_map, &src->specular_map)) + return -1; + if(map_copy_and_release(&dst->specular_exp_map, &src->specular_exp_map)) + return -1; + if(map_copy_and_release(&dst->bump_map, &src->bump_map)) + return -1; + if(str_copy_and_release(&dst->name, &src->name)) + return -1; + return 0; } +/******************************************************************************* + * Definition of the aw_mtl opaque data structure + ******************************************************************************/ /* Generate the darray_mtl data structure */ #define DARRAY_NAME material #define DARRAY_DATA struct material @@ -143,7 +266,7 @@ parse_color(struct color* col, char** word_tk) if(AW_OK != (res = string_to_float(word, &col->value[0]))) return res; - /* If only the first component is defined the second and third ones are + /* 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, " ", word_tk); if(!word) { @@ -191,6 +314,65 @@ parse_size_t } static enum aw_result +parse_bool_option + (int* mask_options, + const enum map_flag option, + char** tk_ctxt) +{ + char* word; + ASSERT(mask_options && tk_ctxt); + word = strtok_r(NULL, " ", tk_ctxt); + if(!word) + return AW_BAD_ARGUMENT; + if(strcmp(word, "on") == 0) { + *mask_options |= (int)option; + } else if(strcmp(word, "off") != 0) { + return AW_BAD_ARGUMENT; + } + return AW_OK; +} + +static enum aw_result +parse_map(struct map* map, char** tk_ctxt) +{ + char* word; + ASSERT(map && tk_ctxt); + + word = strtok_r(NULL, " ", tk_ctxt); + while(word) { + enum aw_result res; + + if(!strcmp(word, "-blendu")) { + res = parse_bool_option(&map->mask_options, MAP_BLEND_U, tk_ctxt); + } else if(!strcmp(word, "-blendv")) { + res = parse_bool_option(&map->mask_options, MAP_BLEND_V, tk_ctxt); + } else if(!strcmp(word, "-cc")) { + res = parse_bool_option(&map->mask_options, MAP_COLOR_CORRECTION,tk_ctxt); + } else if(!strcmp(word, "-clamp")) { + res = parse_bool_option(&map->mask_options, MAP_CLAMP, tk_ctxt); + } else if(!strcmp(word, "-imfchan")) { /* Scalar texture channel */ + /* res = parse_imfchan(&map->channel, tk_ctxt); */ + } else if(!strcmp(word, "-mm")) { /* Image bias and scale */ + /* res = parse_float TODO */ + } else if(!strcmp(word, "-o")) { /* Texcoord offset */ + } else if(!strcmp(word, "-s")) { /* Texcoord scale */ + } else if(!strcmp(word, "-t")) { /* Texcoord turbulence */ + } else if(!strcmp(word, "-texres")) { /* Texture resolution */ + } else if(!strcmp(word, "-bm")) { /* Bump multiplier */ + } else { + do { + if(str_append(&map->filename, word)) + return AW_MEMORY_ERROR; + } while((word = strtok_r(NULL, " ", tk_ctxt))); + } + if(res != AW_OK) + return res; + word = strtok_r(NULL, " ", tk_ctxt); + } + return AW_OK; +} + +static enum aw_result parse_mtl_file(struct aw_mtl* mtl, const char* path, char* content) { char* line, *line_tk; @@ -222,14 +404,16 @@ parse_mtl_file(struct aw_mtl* mtl, const char* path, char* content) res = parse_float(&mtl->newmtl->refraction_id, 0.001f, 10.f, &word_tk); } else if(!strcmp(word, "illum")) { /* Illumination model */ res = parse_size_t(&mtl->newmtl->illumination, 0, 10, &word_tk); - } else if(!strcmp(word, "d")) { /* Dissolve factor */ - } else if(!strcmp(word, "sharpness")) { /* Reflection sharpness */ } else if(!strcmp(word, "map_Ka")) { /* Ambient texture */ + res = parse_map(&mtl->newmtl->ambient_map, &word_tk); } else if(!strcmp(word, "map_Kd")) { /* Diffuse texture */ + res = parse_map(&mtl->newmtl->diffuse_map, &word_tk); } else if(!strcmp(word, "map_Ks")) { /* Specular texture */ + res = parse_map(&mtl->newmtl->specular_map, &word_tk); } else if(!strcmp(word, "map_Ns")) { /* Specular exponent texture */ - } else if(!strcmp(word, "map_d")) { /* Dissolve texture */ + res = parse_map(&mtl->newmtl->specular_exp_map, &word_tk); } else if(!strcmp(word, "bump")) { /* Bump map */ + res = parse_map(&mtl->newmtl->bump_map, &word_tk); } else { res = AW_OK; fprintf(stderr, "%s:%lu: warning: ignored or malformed directive %s\n",