Add more support for parsing texture options.
Add more unit testing for texture options.
This commit is contained in:
@@ -3,9 +3,10 @@ Ka 0 0 0
|
|||||||
Kd 0 0 0
|
Kd 0 0 0
|
||||||
Ks 0 0 0
|
Ks 0 0 0
|
||||||
Kt 0.1 0.2 0.3
|
Kt 0.1 0.2 0.3
|
||||||
|
map_Ka -clamp on ambient.jpg
|
||||||
map_Kd -o 0.1 diffuse.jpg
|
map_Kd -o 0.1 diffuse.jpg
|
||||||
map_Ks -o 0.1 0.2 specular.jpg
|
map_Ks -s 0.1 0.2 specular.jpg
|
||||||
map_Ns -o 0.1 0.2 0.3 specular_highlight.jpg
|
map_Ns -t 0.1 0.2 0.3 specular_highlight.jpg
|
||||||
map_bump -bm 3 bumpmap.jpg
|
map_bump -bm 3 bumpmap.jpg
|
||||||
|
|
||||||
newmtl bm2
|
newmtl bm2
|
||||||
@@ -16,5 +17,20 @@ Kt 0.1 0.2 0.3
|
|||||||
# blendu
|
# blendu
|
||||||
map_Kd -blendu on diffuse.jpg
|
map_Kd -blendu on diffuse.jpg
|
||||||
map_Ks -blendv off specular.jpg
|
map_Ks -blendv off specular.jpg
|
||||||
|
map_Ns -mm 0.1 0.3 specular_highlight.jpg
|
||||||
# -bm after filename
|
# -bm after filename
|
||||||
map_bump bumpmap2.jpg -bm 1.5
|
map_bump -imfchan r bumpmap2.jpg -bm 1.5
|
||||||
|
|
||||||
|
newmtl bm3
|
||||||
|
Ka 0 0 0
|
||||||
|
Kd 0 0 0
|
||||||
|
Ks 0 0 0
|
||||||
|
Kt 0.1 0.2 0.3
|
||||||
|
# type
|
||||||
|
map_Kd -type sphere diffuse.jpg
|
||||||
|
map_Ks -type cube_top specular.jpg
|
||||||
|
map_Ns -type cube_bottom specular_highlight.jpg
|
||||||
|
map_Ka -type cube_left ambient.jpg
|
||||||
|
map_d -type cube_right alpha.jpg
|
||||||
|
map_bump -type cube_front bump.jpg
|
||||||
|
disp -type cube_back displacement.jpg
|
||||||
|
|||||||
@@ -488,6 +488,48 @@ TEST_CASE("usemtl_at_last_line", "[Issue104]") {
|
|||||||
REQUIRE(1 == shapes.size());
|
REQUIRE(1 == shapes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("texture_opts", "[Issue85]") {
|
||||||
|
tinyobj::attrib_t attrib;
|
||||||
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
|
std::vector<tinyobj::material_t> materials;
|
||||||
|
|
||||||
|
std::string err;
|
||||||
|
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, "../models/texture-options-issue-85.obj", gMtlBasePath);
|
||||||
|
|
||||||
|
if (!err.empty()) {
|
||||||
|
std::cerr << err << std::endl;
|
||||||
|
}
|
||||||
|
REQUIRE(true == ret);
|
||||||
|
REQUIRE(1 == shapes.size());
|
||||||
|
REQUIRE(3 == materials.size());
|
||||||
|
REQUIRE(0 == materials[0].name.compare("default"));
|
||||||
|
REQUIRE(0 == materials[1].name.compare("bm2"));
|
||||||
|
REQUIRE(0 == materials[2].name.compare("bm3"));
|
||||||
|
REQUIRE(true == materials[0].ambient_texopt.clamp);
|
||||||
|
REQUIRE(0.1 == Approx(materials[0].diffuse_texopt.origin_offset[0]));
|
||||||
|
REQUIRE(0.0 == Approx(materials[0].diffuse_texopt.origin_offset[1]));
|
||||||
|
REQUIRE(0.0 == Approx(materials[0].diffuse_texopt.origin_offset[2]));
|
||||||
|
REQUIRE(0.1 == Approx(materials[0].specular_texopt.scale[0]));
|
||||||
|
REQUIRE(0.2 == Approx(materials[0].specular_texopt.scale[1]));
|
||||||
|
REQUIRE(1.0 == Approx(materials[0].specular_texopt.scale[2]));
|
||||||
|
REQUIRE(0.1 == Approx(materials[0].specular_highlight_texopt.turbulence[0]));
|
||||||
|
REQUIRE(0.2 == Approx(materials[0].specular_highlight_texopt.turbulence[1]));
|
||||||
|
REQUIRE(0.3 == Approx(materials[0].specular_highlight_texopt.turbulence[2]));
|
||||||
|
REQUIRE(3.0 == Approx(materials[0].bump_texopt.bump_multiplier));
|
||||||
|
|
||||||
|
REQUIRE(0.1 == Approx(materials[1].specular_highlight_texopt.brightness));
|
||||||
|
REQUIRE(0.3 == Approx(materials[1].specular_highlight_texopt.contrast));
|
||||||
|
REQUIRE('r' == materials[1].bump_texopt.imfchan);
|
||||||
|
|
||||||
|
REQUIRE(tinyobj::TEXTURE_TYPE_SPHERE == materials[2].diffuse_texopt.type);
|
||||||
|
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_TOP == materials[2].specular_texopt.type);
|
||||||
|
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_BOTTOM == materials[2].specular_highlight_texopt.type);
|
||||||
|
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_LEFT == materials[2].ambient_texopt.type);
|
||||||
|
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_RIGHT == materials[2].alpha_texopt.type);
|
||||||
|
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_FRONT == materials[2].bump_texopt.type);
|
||||||
|
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_BACK == materials[2].displacement_texopt.type);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int
|
int
|
||||||
main(
|
main(
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ THE SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
// version 1.0.2 : Improve parsing speed by about a factor of 2 for large files(#105)
|
// version 1.0.3 : Support parsing texture options(#85)
|
||||||
|
// version 1.0.2 : Improve parsing speed by about a factor of 2 for large
|
||||||
|
// files(#105)
|
||||||
// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104)
|
// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104)
|
||||||
// version 1.0.0 : Change data structure. Change license from BSD to MIT.
|
// version 1.0.0 : Change data structure. Change license from BSD to MIT.
|
||||||
//
|
//
|
||||||
@@ -44,38 +46,56 @@ THE SOFTWARE.
|
|||||||
namespace tinyobj {
|
namespace tinyobj {
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ...
|
// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ...
|
||||||
//
|
//
|
||||||
// -blendu on | off # set horizontal texture blending (default on)
|
// -blendu on | off # set horizontal texture blending
|
||||||
// -blendv on | off # set vertical texture blending (default on)
|
// (default on)
|
||||||
|
// -blendv on | off # set vertical texture blending
|
||||||
|
// (default on)
|
||||||
// -boost float_value # boost mip-map sharpness
|
// -boost float_value # boost mip-map sharpness
|
||||||
// -mm base_value gain_value # modify texture map values (default 0 1)
|
// -mm base_value gain_value # modify texture map values (default
|
||||||
// # base_value = brightness, gain_value = contrast
|
// 0 1)
|
||||||
// -o u [v [w]] # Origin offset (default 0 0 0)
|
// # base_value = brightness,
|
||||||
// -s u [v [w]] # Scale (default 1 1 1)
|
// gain_value = contrast
|
||||||
// -t u [v [w]] # Turbulence (default 0 0 0)
|
// -o u [v [w]] # Origin offset (default
|
||||||
|
// 0 0 0)
|
||||||
|
// -s u [v [w]] # Scale (default
|
||||||
|
// 1 1 1)
|
||||||
|
// -t u [v [w]] # Turbulence (default
|
||||||
|
// 0 0 0)
|
||||||
// -texres resolution # texture resolution to create
|
// -texres resolution # texture resolution to create
|
||||||
// -clamp on | off # only render texels in the clamped 0-1 range (default off)
|
// -clamp on | off # only render texels in the clamped
|
||||||
// # When unclamped, textures are repeated across a surface,
|
// 0-1 range (default off)
|
||||||
// # when clamped, only texels which fall within the 0-1
|
// # When unclamped, textures are
|
||||||
|
// repeated across a surface,
|
||||||
|
// # when clamped, only texels which
|
||||||
|
// fall within the 0-1
|
||||||
// # range are rendered.
|
// # range are rendered.
|
||||||
// -bm mult_value # bump multiplier (for bump maps only)
|
// -bm mult_value # bump multiplier (for bump maps
|
||||||
//
|
// only)
|
||||||
// -imfchan r | g | b | m | l | z # specifies which channel of the file is used to
|
//
|
||||||
// # create a scalar or bump texture. r:red, g:green,
|
// -imfchan r | g | b | m | l | z # specifies which channel of the file
|
||||||
// # b:blue, m:matte, l:luminance, z:z-depth..
|
// is used to
|
||||||
// # (the default for bump is 'l' and for decal is 'm')
|
// # create a scalar or bump texture.
|
||||||
// bump -imfchan r bumpmap.tga # says to use the red channel of bumpmap.tga as the bumpmap
|
// r:red, g:green,
|
||||||
|
// # b:blue, m:matte, l:luminance,
|
||||||
|
// z:z-depth..
|
||||||
|
// # (the default for bump is 'l' and
|
||||||
|
// for decal is 'm')
|
||||||
|
// bump -imfchan r bumpmap.tga # says to use the red channel of
|
||||||
|
// bumpmap.tga as the bumpmap
|
||||||
//
|
//
|
||||||
// For reflection maps...
|
// For reflection maps...
|
||||||
//
|
//
|
||||||
// -type sphere # specifies a sphere for a "refl" reflection map
|
// -type sphere # specifies a sphere for a "refl"
|
||||||
// -type cube_top | cube_bottom | # when using a cube map, the texture file for each
|
// reflection map
|
||||||
// cube_front | cube_back | # side of the cube is specified separately
|
// -type cube_top | cube_bottom | # when using a cube map, the texture
|
||||||
|
// file for each
|
||||||
|
// cube_front | cube_back | # side of the cube is specified
|
||||||
|
// separately
|
||||||
// cube_left | cube_right
|
// cube_left | cube_right
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TEXTURE_TYPE_NONE, // default
|
TEXTURE_TYPE_NONE, // default
|
||||||
TEXTURE_TYPE_SPHERE,
|
TEXTURE_TYPE_SPHERE,
|
||||||
TEXTURE_TYPE_CUBE_TOP,
|
TEXTURE_TYPE_CUBE_TOP,
|
||||||
TEXTURE_TYPE_CUBE_BOTTOM,
|
TEXTURE_TYPE_CUBE_BOTTOM,
|
||||||
@@ -84,21 +104,21 @@ typedef enum {
|
|||||||
TEXTURE_TYPE_CUBE_LEFT,
|
TEXTURE_TYPE_CUBE_LEFT,
|
||||||
TEXTURE_TYPE_CUBE_RIGHT
|
TEXTURE_TYPE_CUBE_RIGHT
|
||||||
} texture_type_t;
|
} texture_type_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
texture_type_t type; // -type (default TEXTURE_TYPE_NONE)
|
texture_type_t type; // -type (default TEXTURE_TYPE_NONE)
|
||||||
float sharpness; // -boost (default 1.0?)
|
float sharpness; // -boost (default 1.0?)
|
||||||
float brightness; // base_value in -mm option (default 0)
|
float brightness; // base_value in -mm option (default 0)
|
||||||
float contrast; // gain_value in -mm option (default 1)
|
float contrast; // gain_value in -mm option (default 1)
|
||||||
float origin_offset[3]; // -o u [v [w]] (default 0 0 0)
|
float origin_offset[3]; // -o u [v [w]] (default 0 0 0)
|
||||||
float scale[3]; // -s u [v [w]] (default 1 1 1)
|
float scale[3]; // -s u [v [w]] (default 1 1 1)
|
||||||
float turbulence[3]; // -t u [v [w]] (default 0 0 0)
|
float turbulence[3]; // -t u [v [w]] (default 0 0 0)
|
||||||
//int texture_resolution; // -texres resolution (default = ?) TODO
|
// int texture_resolution; // -texres resolution (default = ?) TODO
|
||||||
bool clamp; // -clamp (default false)
|
bool clamp; // -clamp (default false)
|
||||||
char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm')
|
char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm')
|
||||||
bool blendu; // -blendu (default on)
|
bool blendu; // -blendu (default on)
|
||||||
bool blendv; // -blendv (default on)
|
bool blendv; // -blendv (default on)
|
||||||
float bump_multiplier; // -bm (for bump maps only, default 1.0)
|
float bump_multiplier; // -bm (for bump maps only, default 1.0)
|
||||||
} texture_option_t;
|
} texture_option_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -135,13 +155,13 @@ typedef struct {
|
|||||||
|
|
||||||
// PBR extension
|
// PBR extension
|
||||||
// http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr
|
// http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr
|
||||||
float roughness; // [0, 1] default 0
|
float roughness; // [0, 1] default 0
|
||||||
float metallic; // [0, 1] default 0
|
float metallic; // [0, 1] default 0
|
||||||
float sheen; // [0, 1] default 0
|
float sheen; // [0, 1] default 0
|
||||||
float clearcoat_thickness; // [0, 1] default 0
|
float clearcoat_thickness; // [0, 1] default 0
|
||||||
float clearcoat_roughness; // [0, 1] default 0
|
float clearcoat_roughness; // [0, 1] default 0
|
||||||
float anisotropy; // aniso. [0, 1] default 0
|
float anisotropy; // aniso. [0, 1] default 0
|
||||||
float anisotropy_rotation; // anisor. [0, 1] default 0
|
float anisotropy_rotation; // anisor. [0, 1] default 0
|
||||||
float pad0;
|
float pad0;
|
||||||
float pad1;
|
float pad1;
|
||||||
std::string roughness_texname; // map_Pr
|
std::string roughness_texname; // map_Pr
|
||||||
@@ -496,20 +516,13 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
|||||||
end_not_reached = (curr != s_end);
|
end_not_reached = (curr != s_end);
|
||||||
while (end_not_reached && IS_DIGIT(*curr)) {
|
while (end_not_reached && IS_DIGIT(*curr)) {
|
||||||
static const double pow_lut[] = {
|
static const double pow_lut[] = {
|
||||||
1.0,
|
1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001,
|
||||||
0.1,
|
|
||||||
0.01,
|
|
||||||
0.001,
|
|
||||||
0.0001,
|
|
||||||
0.00001,
|
|
||||||
0.000001,
|
|
||||||
0.0000001,
|
|
||||||
};
|
};
|
||||||
const int lut_entries = sizeof pow_lut / sizeof pow_lut[0];
|
const int lut_entries = sizeof pow_lut / sizeof pow_lut[0];
|
||||||
|
|
||||||
// NOTE: Don't use powf here, it will absolutely murder precision.
|
// NOTE: Don't use powf here, it will absolutely murder precision.
|
||||||
mantissa += static_cast<int>(*curr - 0x30) *
|
mantissa += static_cast<int>(*curr - 0x30) *
|
||||||
(read < lut_entries ? pow_lut[read] : pow(10.0, -read));
|
(read < lut_entries ? pow_lut[read] : pow(10.0, -read));
|
||||||
read++;
|
read++;
|
||||||
curr++;
|
curr++;
|
||||||
end_not_reached = (curr != s_end);
|
end_not_reached = (curr != s_end);
|
||||||
@@ -549,8 +562,9 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assemble:
|
assemble:
|
||||||
*result = (sign == '+' ? 1 : -1) *
|
*result =
|
||||||
(exponent ? ldexp(mantissa * pow(5.0, exponent), exponent) : mantissa);
|
(sign == '+' ? 1 : -1) *
|
||||||
|
(exponent ? ldexp(mantissa * pow(5.0, exponent), exponent) : mantissa);
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
return false;
|
return false;
|
||||||
@@ -566,43 +580,74 @@ static inline float parseFloat(const char **token, double default_value = 0.0) {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void parseFloat2(float *x, float *y, const char **token) {
|
static inline void parseFloat2(float *x, float *y, const char **token,
|
||||||
(*x) = parseFloat(token);
|
const double default_x = 0.0,
|
||||||
(*y) = parseFloat(token);
|
const double default_y = 0.0) {
|
||||||
|
(*x) = parseFloat(token, default_x);
|
||||||
|
(*y) = parseFloat(token, default_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void parseFloat3(float *x, float *y, float *z,
|
static inline void parseFloat3(float *x, float *y, float *z, const char **token,
|
||||||
const char **token) {
|
const double default_x = 0.0,
|
||||||
(*x) = parseFloat(token);
|
const double default_y = 0.0,
|
||||||
(*y) = parseFloat(token);
|
const double default_z = 0.0) {
|
||||||
(*z) = parseFloat(token);
|
(*x) = parseFloat(token, default_x);
|
||||||
|
(*y) = parseFloat(token, default_y);
|
||||||
|
(*z) = parseFloat(token, default_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void parseV(float *x, float *y, float *z, float *w,
|
static inline void parseV(float *x, float *y, float *z, float *w,
|
||||||
const char **token) {
|
const char **token, const double default_x = 0.0,
|
||||||
(*x) = parseFloat(token);
|
const double default_y = 0.0,
|
||||||
(*y) = parseFloat(token);
|
const double default_z = 0.0,
|
||||||
(*z) = parseFloat(token);
|
const double default_w = 1.0) {
|
||||||
(*w) = parseFloat(token, 1.0);
|
(*x) = parseFloat(token, default_x);
|
||||||
|
(*y) = parseFloat(token, default_y);
|
||||||
|
(*z) = parseFloat(token, default_z);
|
||||||
|
(*w) = parseFloat(token, default_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool parseOnOff(const char **token, bool default_value = true) {
|
static inline bool parseOnOff(const char **token, bool default_value = true) {
|
||||||
(*token) += strspn((*token), " \t");
|
(*token) += strspn((*token), " \t");
|
||||||
const char *end = (*token) + strcspn((*token), " \t\r");
|
const char *end = (*token) + strcspn((*token), " \t\r");
|
||||||
|
|
||||||
printf("token = %s\n", (*token));
|
|
||||||
bool ret = default_value;
|
bool ret = default_value;
|
||||||
if ((0 == strncmp((*token), "on", 2))) {
|
if ((0 == strncmp((*token), "on", 2))) {
|
||||||
ret = true;
|
ret = true;
|
||||||
} else if ((0 == strncmp((*token), "off", 3))) {
|
} else if ((0 == strncmp((*token), "off", 3))) {
|
||||||
printf("off\n");
|
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*token) = end;
|
(*token) = end;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline texture_type_t parseTextureType(
|
||||||
|
const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) {
|
||||||
|
(*token) += strspn((*token), " \t");
|
||||||
|
const char *end = (*token) + strcspn((*token), " \t\r");
|
||||||
|
texture_type_t ty = default_value;
|
||||||
|
|
||||||
|
if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) {
|
||||||
|
ty = TEXTURE_TYPE_CUBE_TOP;
|
||||||
|
} else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) {
|
||||||
|
ty = TEXTURE_TYPE_CUBE_BOTTOM;
|
||||||
|
} else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) {
|
||||||
|
ty = TEXTURE_TYPE_CUBE_LEFT;
|
||||||
|
} else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) {
|
||||||
|
ty = TEXTURE_TYPE_CUBE_RIGHT;
|
||||||
|
} else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) {
|
||||||
|
ty = TEXTURE_TYPE_CUBE_FRONT;
|
||||||
|
} else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) {
|
||||||
|
ty = TEXTURE_TYPE_CUBE_BACK;
|
||||||
|
} else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) {
|
||||||
|
ty = TEXTURE_TYPE_SPHERE;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*token) = end;
|
||||||
|
return ty;
|
||||||
|
}
|
||||||
|
|
||||||
static tag_sizes parseTagTriple(const char **token) {
|
static tag_sizes parseTagTriple(const char **token) {
|
||||||
tag_sizes ts;
|
tag_sizes ts;
|
||||||
|
|
||||||
@@ -693,8 +738,9 @@ static vertex_index parseRawTriple(const char **token) {
|
|||||||
return vi;
|
return vi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseTextureNameAndOption(std::string* texname, texture_option_t *texopt, const char* linebuf, const bool is_bump)
|
static bool ParseTextureNameAndOption(std::string *texname,
|
||||||
{
|
texture_option_t *texopt,
|
||||||
|
const char *linebuf, const bool is_bump) {
|
||||||
// @todo { write more robust lexer and parser. }
|
// @todo { write more robust lexer and parser. }
|
||||||
bool found_texname = false;
|
bool found_texname = false;
|
||||||
std::string texture_name;
|
std::string texture_name;
|
||||||
@@ -723,60 +769,58 @@ static bool ParseTextureNameAndOption(std::string* texname, texture_option_t *te
|
|||||||
texopt->turbulence[2] = 0.0f;
|
texopt->turbulence[2] = 0.0f;
|
||||||
texopt->type = TEXTURE_TYPE_NONE;
|
texopt->type = TEXTURE_TYPE_NONE;
|
||||||
|
|
||||||
const char *token = linebuf; // Assume line ends with NULL
|
const char *token = linebuf; // Assume line ends with NULL
|
||||||
|
|
||||||
// @todo { -mm, -type, -imfchan }
|
|
||||||
while (!IS_NEW_LINE((*token))) {
|
while (!IS_NEW_LINE((*token))) {
|
||||||
if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) {
|
if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) {
|
||||||
token += 8;
|
token += 8;
|
||||||
texopt->blendu = parseOnOff(&token, /* default */true);
|
texopt->blendu = parseOnOff(&token, /* default */ true);
|
||||||
printf("blendu = %d\n", texopt->blendu);
|
|
||||||
} else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) {
|
} else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) {
|
||||||
token += 8;
|
token += 8;
|
||||||
texopt->blendv = parseOnOff(&token, /* default */true);
|
texopt->blendv = parseOnOff(&token, /* default */ true);
|
||||||
printf("blendv = %d\n", texopt->blendv);
|
|
||||||
} else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) {
|
} else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) {
|
||||||
token += 7;
|
token += 7;
|
||||||
texopt->clamp = parseOnOff(&token, /* default */true);
|
texopt->clamp = parseOnOff(&token, /* default */ true);
|
||||||
printf("clamp= %d\n", texopt->clamp);
|
|
||||||
} else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) {
|
} else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) {
|
||||||
token += 7;
|
token += 7;
|
||||||
texopt->sharpness = parseFloat(&token, 1.0);
|
texopt->sharpness = parseFloat(&token, 1.0);
|
||||||
printf("boost = %f\n", static_cast<double>(texopt->sharpness));
|
|
||||||
} else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) {
|
} else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) {
|
||||||
token += 4;
|
token += 4;
|
||||||
texopt->bump_multiplier = parseFloat(&token, 1.0);
|
texopt->bump_multiplier = parseFloat(&token, 1.0);
|
||||||
printf("bm %f\n", static_cast<double>(texopt->bump_multiplier));
|
|
||||||
} else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) {
|
} else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
parseFloat3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), &(texopt->origin_offset[2]), &token);
|
parseFloat3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]),
|
||||||
printf("o %f, %f, %f\n",
|
&(texopt->origin_offset[2]), &token);
|
||||||
static_cast<double>(texopt->origin_offset[0]),
|
|
||||||
static_cast<double>(texopt->origin_offset[1]),
|
|
||||||
static_cast<double>(texopt->origin_offset[2]));
|
|
||||||
} else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) {
|
} else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
parseFloat3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), &token);
|
parseFloat3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]),
|
||||||
printf("s %f, %f, %f\n",
|
&token, 1.0, 1.0, 1.0);
|
||||||
static_cast<double>(texopt->scale[0]),
|
|
||||||
static_cast<double>(texopt->scale[1]),
|
|
||||||
static_cast<double>(texopt->scale[2]));
|
|
||||||
} else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) {
|
} else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) {
|
||||||
token += 3;
|
token += 3;
|
||||||
parseFloat3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), &(texopt->turbulence[2]), &token);
|
parseFloat3(&(texopt->turbulence[0]), &(texopt->turbulence[1]),
|
||||||
printf("t %f, %f, %f\n",
|
&(texopt->turbulence[2]), &token);
|
||||||
static_cast<double>(texopt->turbulence[0]),
|
} else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) {
|
||||||
static_cast<double>(texopt->turbulence[1]),
|
token += 5;
|
||||||
static_cast<double>(texopt->turbulence[2]));
|
texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE);
|
||||||
|
} else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) {
|
||||||
|
token += 9;
|
||||||
|
token += strspn(token, " \t");
|
||||||
|
const char *end = token + strcspn(token, " \t\r");
|
||||||
|
if ((end - token) == 1) { // Assume one char for -imfchan
|
||||||
|
texopt->imfchan = (*token);
|
||||||
|
}
|
||||||
|
token = end;
|
||||||
|
} else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) {
|
||||||
|
token += 4;
|
||||||
|
parseFloat2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0);
|
||||||
} else {
|
} else {
|
||||||
// Assume texture filename
|
// Assume texture filename
|
||||||
token += strspn(token, " \t"); // skip space
|
token += strspn(token, " \t"); // skip space
|
||||||
size_t len = strcspn(token, " \t\r"); // untile next space
|
size_t len = strcspn(token, " \t\r"); // untile next space
|
||||||
texture_name = std::string(token, token + len);
|
texture_name = std::string(token, token + len);
|
||||||
printf("texname = [%s]\n", texture_name.c_str());
|
|
||||||
token += len;
|
token += len;
|
||||||
|
|
||||||
token += strspn(token, " \t"); // skip space
|
token += strspn(token, " \t"); // skip space
|
||||||
|
|
||||||
found_texname = true;
|
found_texname = true;
|
||||||
}
|
}
|
||||||
@@ -790,8 +834,6 @@ static bool ParseTextureNameAndOption(std::string* texname, texture_option_t *te
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void InitMaterial(material_t *material) {
|
static void InitMaterial(material_t *material) {
|
||||||
material->name = "";
|
material->name = "";
|
||||||
material->ambient_texname = "";
|
material->ambient_texname = "";
|
||||||
@@ -1097,42 +1139,54 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
// ambient texture
|
// ambient texture
|
||||||
if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
material.ambient_texname = token;
|
ParseTextureNameAndOption(&(material.ambient_texname),
|
||||||
|
&(material.ambient_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// diffuse texture
|
// diffuse texture
|
||||||
if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
ParseTextureNameAndOption(&(material.diffuse_texname), &(material.diffuse_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.diffuse_texname),
|
||||||
|
&(material.diffuse_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// specular texture
|
// specular texture
|
||||||
if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
ParseTextureNameAndOption(&(material.specular_texname), &(material.specular_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.specular_texname),
|
||||||
|
&(material.specular_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// specular highlight texture
|
// specular highlight texture
|
||||||
if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
ParseTextureNameAndOption(&(material.specular_highlight_texname), &(material.specular_highlight_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.specular_highlight_texname),
|
||||||
|
&(material.specular_highlight_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bump texture
|
// bump texture
|
||||||
if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) {
|
if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) {
|
||||||
token += 9;
|
token += 9;
|
||||||
ParseTextureNameAndOption(&(material.bump_texname), &(material.bump_texopt), token, /* is_bump */true);
|
ParseTextureNameAndOption(&(material.bump_texname),
|
||||||
|
&(material.bump_texopt), token,
|
||||||
|
/* is_bump */ true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bump texture
|
// bump texture
|
||||||
if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) {
|
if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) {
|
||||||
token += 5;
|
token += 5;
|
||||||
ParseTextureNameAndOption(&(material.bump_texname), &(material.bump_texopt), token, /* is_bump */true);
|
ParseTextureNameAndOption(&(material.bump_texname),
|
||||||
|
&(material.bump_texopt), token,
|
||||||
|
/* is_bump */ true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1140,49 +1194,63 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
|||||||
if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) {
|
if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) {
|
||||||
token += 6;
|
token += 6;
|
||||||
material.alpha_texname = token;
|
material.alpha_texname = token;
|
||||||
ParseTextureNameAndOption(&(material.alpha_texname), &(material.alpha_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.alpha_texname),
|
||||||
|
&(material.alpha_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// displacement texture
|
// displacement texture
|
||||||
if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) {
|
if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) {
|
||||||
token += 5;
|
token += 5;
|
||||||
ParseTextureNameAndOption(&(material.displacement_texname), &(material.displacement_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.displacement_texname),
|
||||||
|
&(material.displacement_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: roughness texture
|
// PBR: roughness texture
|
||||||
if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
ParseTextureNameAndOption(&(material.roughness_texname), &(material.roughness_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.roughness_texname),
|
||||||
|
&(material.roughness_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: metallic texture
|
// PBR: metallic texture
|
||||||
if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
ParseTextureNameAndOption(&(material.metallic_texname), &(material.metallic_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.metallic_texname),
|
||||||
|
&(material.metallic_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: sheen texture
|
// PBR: sheen texture
|
||||||
if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
ParseTextureNameAndOption(&(material.sheen_texname), &(material.sheen_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.sheen_texname),
|
||||||
|
&(material.sheen_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: emissive texture
|
// PBR: emissive texture
|
||||||
if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) {
|
if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) {
|
||||||
token += 7;
|
token += 7;
|
||||||
ParseTextureNameAndOption(&(material.emissive_texname), &(material.emissive_texopt), token, /* is_bump */false);
|
ParseTextureNameAndOption(&(material.emissive_texname),
|
||||||
|
&(material.emissive_texopt), token,
|
||||||
|
/* is_bump */ false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PBR: normal map texture
|
// PBR: normal map texture
|
||||||
if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) {
|
if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) {
|
||||||
token += 5;
|
token += 5;
|
||||||
ParseTextureNameAndOption(&(material.normal_texname), &(material.normal_texopt), token, /* is_bump */false); // @fixme { is_bump will be true? }
|
ParseTextureNameAndOption(
|
||||||
|
&(material.normal_texname), &(material.normal_texopt), token,
|
||||||
|
/* is_bump */ false); // @fixme { is_bump will be true? }
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1279,8 +1347,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
|||||||
|
|
||||||
bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||||
std::vector<material_t> *materials, std::string *err,
|
std::vector<material_t> *materials, std::string *err,
|
||||||
std::istream *inStream,
|
std::istream *inStream, MaterialReader *readMatFn /*= NULL*/,
|
||||||
MaterialReader *readMatFn /*= NULL*/,
|
|
||||||
bool triangulate) {
|
bool triangulate) {
|
||||||
std::stringstream errss;
|
std::stringstream errss;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user