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:
| M | src/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",