Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAras Pranckevicius <aras@nesnausk.org>2022-05-12 13:48:55 +0300
committerAras Pranckevicius <aras@nesnausk.org>2022-05-12 13:49:05 +0300
commit9757b4efb12e0fba21735fa7960148e6a7b67bb2 (patch)
treef10d73e9d57b840fe20131a069b75171d6d2fe17 /source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
parent207b0c2a0f792375ea7a3087823af41621ececd2 (diff)
OBJ: improve new importer file parsing performance on windows
The OBJ parser was primarily using StringRef for convenience, with functions like "skip whitespace" or "parse a number" taking an input stringref, representing an input line, and returning a new stringref, representing the remainder of the line. This is convenient, but does more work than strictly needed -- while parsing, only the "beginning" of the line ever changes by moving forward; the end of the line always stays the same. We can change the code to take a pair of pointers (begin of line, end of line) as input, and make the functions return the new begin of line pointer. This makes the return value neatly fit into a processor register, which StringRef did not. On Windows, this does result in non-trivial speedups in the actual OBJ file parsing part, due to Windows calling convention where return values larger than 64 bits are returned via memory. Does not measurably affect performance on Mac/Linux, because the calling convention there uses a pair of 64-bit registers to return a StringRef. End-to-end times of importing several test files, on Windows (VS2022 build, Ryzen 5950X): - Monkey subdivided to level 6, no normals (220MB file): 1.25s -> 0.85s - Rungholt minecraft level (270MB file): 7.0s -> 5.8s - Blender 3 splash scene (2.4GB file): 49.1s -> 45.5s The full import process has a lot of other overhead besides actual OBJ file parsing (mostly creating actual blender objects out of parsed data). In pure parsing, in the monkey test scene above, the parsing part goes 1.0s -> 0.6s. Reviewed By: Howard Trickey Differential Revision: https://developer.blender.org/D14936
Diffstat (limited to 'source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc')
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc294
1 files changed, 158 insertions, 136 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
index fa89b49b605..c7990028312 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
@@ -66,40 +66,43 @@ static Geometry *create_geometry(Geometry *const prev_geometry,
}
static void geom_add_vertex(Geometry *geom,
- const StringRef line,
+ const char *p,
+ const char *end,
GlobalVertices &r_global_vertices)
{
float3 vert;
- parse_floats(line, 0.0f, vert, 3);
+ parse_floats(p, end, 0.0f, vert, 3);
r_global_vertices.vertices.append(vert);
geom->vertex_count_++;
}
static void geom_add_vertex_normal(Geometry *geom,
- const StringRef line,
+ const char *p,
+ const char *end,
GlobalVertices &r_global_vertices)
{
float3 normal;
- parse_floats(line, 0.0f, normal, 3);
+ parse_floats(p, end, 0.0f, normal, 3);
r_global_vertices.vertex_normals.append(normal);
geom->has_vertex_normals_ = true;
}
-static void geom_add_uv_vertex(const StringRef line, GlobalVertices &r_global_vertices)
+static void geom_add_uv_vertex(const char *p, const char *end, GlobalVertices &r_global_vertices)
{
float2 uv;
- parse_floats(line, 0.0f, uv, 2);
+ parse_floats(p, end, 0.0f, uv, 2);
r_global_vertices.uv_vertices.append(uv);
}
static void geom_add_edge(Geometry *geom,
- StringRef line,
+ const char *p,
+ const char *end,
const VertexIndexOffset &offsets,
GlobalVertices &r_global_vertices)
{
int edge_v1, edge_v2;
- line = parse_int(line, -1, edge_v1);
- line = parse_int(line, -1, edge_v2);
+ p = parse_int(p, end, -1, edge_v1);
+ p = parse_int(p, end, -1, edge_v2);
/* Always keep stored indices non-negative and zero-based. */
edge_v1 += edge_v1 < 0 ? r_global_vertices.vertices.size() : -offsets.get_index_offset() - 1;
edge_v2 += edge_v2 < 0 ? r_global_vertices.vertices.size() : -offsets.get_index_offset() - 1;
@@ -108,7 +111,8 @@ static void geom_add_edge(Geometry *geom,
}
static void geom_add_polygon(Geometry *geom,
- StringRef line,
+ const char *p,
+ const char *end,
const GlobalVertices &global_vertices,
const VertexIndexOffset &offsets,
const int material_index,
@@ -127,24 +131,24 @@ static void geom_add_polygon(Geometry *geom,
curr_face.start_index_ = orig_corners_size;
bool face_valid = true;
- line = drop_whitespace(line);
- while (!line.is_empty() && face_valid) {
+ p = drop_whitespace(p, end);
+ while (p < end && face_valid) {
PolyCorner corner;
bool got_uv = false, got_normal = false;
/* Parse vertex index. */
- line = parse_int(line, INT32_MAX, corner.vert_index, false);
+ p = parse_int(p, end, INT32_MAX, corner.vert_index, false);
face_valid &= corner.vert_index != INT32_MAX;
- if (!line.is_empty() && line[0] == '/') {
+ if (p < end && *p == '/') {
/* Parse UV index. */
- line = line.drop_prefix(1);
- if (!line.is_empty() && line[0] != '/') {
- line = parse_int(line, INT32_MAX, corner.uv_vert_index, false);
+ ++p;
+ if (p < end && *p != '/') {
+ p = parse_int(p, end, INT32_MAX, corner.uv_vert_index, false);
got_uv = corner.uv_vert_index != INT32_MAX;
}
/* Parse normal index. */
- if (!line.is_empty() && line[0] == '/') {
- line = line.drop_prefix(1);
- line = parse_int(line, INT32_MAX, corner.vertex_normal_index, false);
+ if (p < end && *p == '/') {
+ ++p;
+ p = parse_int(p, end, INT32_MAX, corner.vertex_normal_index, false);
got_normal = corner.uv_vert_index != INT32_MAX;
}
}
@@ -185,7 +189,7 @@ static void geom_add_polygon(Geometry *geom,
curr_face.corner_count_++;
/* Skip whitespace to get to the next face corner. */
- line = drop_whitespace(line);
+ p = drop_whitespace(p, end);
}
if (face_valid) {
@@ -200,14 +204,16 @@ static void geom_add_polygon(Geometry *geom,
}
static Geometry *geom_set_curve_type(Geometry *geom,
- const StringRef rest_line,
+ const char *p,
+ const char *end,
const GlobalVertices &global_vertices,
const StringRef group_name,
VertexIndexOffset &r_offsets,
Vector<std::unique_ptr<Geometry>> &r_all_geometries)
{
- if (rest_line.find("bspline") == StringRef::not_found) {
- std::cerr << "Curve type not supported:'" << rest_line << "'" << std::endl;
+ p = drop_whitespace(p, end);
+ if (!StringRef(p, end).startswith("bspline")) {
+ std::cerr << "Curve type not supported: '" << std::string(p, end) << "'" << std::endl;
return geom;
}
geom = create_geometry(
@@ -216,22 +222,23 @@ static Geometry *geom_set_curve_type(Geometry *geom,
return geom;
}
-static void geom_set_curve_degree(Geometry *geom, const StringRef line)
+static void geom_set_curve_degree(Geometry *geom, const char *p, const char *end)
{
- parse_int(line, 3, geom->nurbs_element_.degree);
+ parse_int(p, end, 3, geom->nurbs_element_.degree);
}
static void geom_add_curve_vertex_indices(Geometry *geom,
- StringRef line,
+ const char *p,
+ const char *end,
const GlobalVertices &global_vertices)
{
/* Curve lines always have "0.0" and "1.0", skip over them. */
float dummy[2];
- line = parse_floats(line, 0, dummy, 2);
+ p = parse_floats(p, end, 0, dummy, 2);
/* Parse indices. */
- while (!line.is_empty()) {
+ while (p < end) {
int index;
- line = parse_int(line, INT32_MAX, index);
+ p = parse_int(p, end, INT32_MAX, index);
if (index == INT32_MAX) {
return;
}
@@ -241,22 +248,22 @@ static void geom_add_curve_vertex_indices(Geometry *geom,
}
}
-static void geom_add_curve_parameters(Geometry *geom, StringRef line)
+static void geom_add_curve_parameters(Geometry *geom, const char *p, const char *end)
{
- line = drop_whitespace(line);
- if (line.is_empty()) {
- std::cerr << "Invalid OBJ curve parm line: '" << line << "'" << std::endl;
+ p = drop_whitespace(p, end);
+ if (p == end) {
+ std::cerr << "Invalid OBJ curve parm line" << std::endl;
return;
}
- if (line[0] != 'u') {
- std::cerr << "OBJ curve surfaces are not supported: '" << line[0] << "'" << std::endl;
+ if (*p != 'u') {
+ std::cerr << "OBJ curve surfaces are not supported: '" << *p << "'" << std::endl;
return;
}
- line = line.drop_prefix(1);
+ ++p;
- while (!line.is_empty()) {
+ while (p < end) {
float val;
- line = parse_float(line, FLT_MAX, val);
+ p = parse_float(p, end, FLT_MAX, val);
if (val != FLT_MAX) {
geom->nurbs_element_.parm.append(val);
}
@@ -269,7 +276,6 @@ static void geom_add_curve_parameters(Geometry *geom, StringRef line)
static void geom_update_group(const StringRef rest_line, std::string &r_group_name)
{
-
if (rest_line.find("off") != string::npos || rest_line.find("null") != string::npos ||
rest_line.find("default") != string::npos) {
/* Set group for future elements like faces or curves to empty. */
@@ -279,17 +285,18 @@ static void geom_update_group(const StringRef rest_line, std::string &r_group_na
r_group_name = rest_line;
}
-static void geom_update_smooth_group(StringRef line, bool &r_state_shaded_smooth)
+static void geom_update_smooth_group(const char *p, const char *end, bool &r_state_shaded_smooth)
{
- line = drop_whitespace(line);
+ p = drop_whitespace(p, end);
/* Some implementations use "0" and "null" too, in addition to "off". */
+ const StringRef line = StringRef(p, end);
if (line == "0" || line.startswith("off") || line.startswith("null")) {
r_state_shaded_smooth = false;
return;
}
int smooth = 0;
- parse_int(line, 0, smooth);
+ parse_int(p, end, 0, smooth);
r_state_shaded_smooth = smooth != 0;
}
@@ -311,21 +318,21 @@ OBJParser::~OBJParser()
}
/* If line starts with keyword followed by whitespace, returns true and drops it from the line. */
-static bool parse_keyword(StringRef &line, StringRef keyword)
+static bool parse_keyword(const char *&p, const char *end, StringRef keyword)
{
const size_t keyword_len = keyword.size();
- if (line.size() < keyword_len + 1) {
+ if (end - p < keyword_len + 1) {
return false;
}
- if (!line.startswith(keyword)) {
+ if (memcmp(p, keyword.data(), keyword_len) != 0) {
return false;
}
/* Treat any ASCII control character as white-space;
* don't use `isspace()` for performance reasons. */
- if (line[keyword_len] > ' ') {
+ if (p[keyword_len] > ' ') {
return false;
}
- line = line.drop_prefix(keyword_len + 1);
+ p += keyword_len + 1;
return true;
}
@@ -399,27 +406,29 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
StringRef buffer_str{buffer.data(), (int64_t)last_nl};
while (!buffer_str.is_empty()) {
StringRef line = read_next_line(buffer_str);
- line = drop_whitespace(line);
+ const char *p = line.begin(), *end = line.end();
+ p = drop_whitespace(p, end);
++line_number;
- if (line.is_empty()) {
+ if (p == end) {
continue;
}
/* Most common things that start with 'v': vertices, normals, UVs. */
- if (line[0] == 'v') {
- if (parse_keyword(line, "v")) {
- geom_add_vertex(curr_geom, line, r_global_vertices);
+ if (*p == 'v') {
+ if (parse_keyword(p, end, "v")) {
+ geom_add_vertex(curr_geom, p, end, r_global_vertices);
}
- else if (parse_keyword(line, "vn")) {
- geom_add_vertex_normal(curr_geom, line, r_global_vertices);
+ else if (parse_keyword(p, end, "vn")) {
+ geom_add_vertex_normal(curr_geom, p, end, r_global_vertices);
}
- else if (parse_keyword(line, "vt")) {
- geom_add_uv_vertex(line, r_global_vertices);
+ else if (parse_keyword(p, end, "vt")) {
+ geom_add_uv_vertex(p, end, r_global_vertices);
}
}
/* Faces. */
- else if (parse_keyword(line, "f")) {
+ else if (parse_keyword(p, end, "f")) {
geom_add_polygon(curr_geom,
- line,
+ p,
+ end,
r_global_vertices,
offsets,
state_material_index,
@@ -427,20 +436,24 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
state_shaded_smooth);
}
/* Faces. */
- else if (parse_keyword(line, "l")) {
- geom_add_edge(curr_geom, line, offsets, r_global_vertices);
+ else if (parse_keyword(p, end, "l")) {
+ geom_add_edge(curr_geom, p, end, offsets, r_global_vertices);
}
/* Objects. */
- else if (parse_keyword(line, "o")) {
+ else if (parse_keyword(p, end, "o")) {
state_shaded_smooth = false;
state_group_name = "";
state_material_name = "";
- curr_geom = create_geometry(
- curr_geom, GEOM_MESH, line.trim(), r_global_vertices, r_all_geometries, offsets);
+ curr_geom = create_geometry(curr_geom,
+ GEOM_MESH,
+ StringRef(p, end).trim(),
+ r_global_vertices,
+ r_all_geometries,
+ offsets);
}
/* Groups. */
- else if (parse_keyword(line, "g")) {
- geom_update_group(line.trim(), state_group_name);
+ else if (parse_keyword(p, end, "g")) {
+ geom_update_group(StringRef(p, end).trim(), state_group_name);
int new_index = curr_geom->group_indices_.size();
state_group_index = curr_geom->group_indices_.lookup_or_add(state_group_name, new_index);
if (new_index == state_group_index) {
@@ -448,12 +461,12 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
}
}
/* Smoothing groups. */
- else if (parse_keyword(line, "s")) {
- geom_update_smooth_group(line, state_shaded_smooth);
+ else if (parse_keyword(p, end, "s")) {
+ geom_update_smooth_group(p, end, state_shaded_smooth);
}
/* Materials and their libraries. */
- else if (parse_keyword(line, "usemtl")) {
- state_material_name = line.trim();
+ else if (parse_keyword(p, end, "usemtl")) {
+ state_material_name = StringRef(p, end).trim();
int new_mat_index = curr_geom->material_indices_.size();
state_material_index = curr_geom->material_indices_.lookup_or_add(state_material_name,
new_mat_index);
@@ -461,32 +474,32 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
curr_geom->material_order_.append(state_material_name);
}
}
- else if (parse_keyword(line, "mtllib")) {
- add_mtl_library(line.trim());
+ else if (parse_keyword(p, end, "mtllib")) {
+ add_mtl_library(StringRef(p, end).trim());
}
/* Comments. */
- else if (line.startswith("#")) {
+ else if (*p == '#') {
/* Nothing to do. */
}
/* Curve related things. */
- else if (parse_keyword(line, "cstype")) {
+ else if (parse_keyword(p, end, "cstype")) {
curr_geom = geom_set_curve_type(
- curr_geom, line, r_global_vertices, state_group_name, offsets, r_all_geometries);
+ curr_geom, p, end, r_global_vertices, state_group_name, offsets, r_all_geometries);
}
- else if (parse_keyword(line, "deg")) {
- geom_set_curve_degree(curr_geom, line);
+ else if (parse_keyword(p, end, "deg")) {
+ geom_set_curve_degree(curr_geom, p, end);
}
- else if (parse_keyword(line, "curv")) {
- geom_add_curve_vertex_indices(curr_geom, line, r_global_vertices);
+ else if (parse_keyword(p, end, "curv")) {
+ geom_add_curve_vertex_indices(curr_geom, p, end, r_global_vertices);
}
- else if (parse_keyword(line, "parm")) {
- geom_add_curve_parameters(curr_geom, line);
+ else if (parse_keyword(p, end, "parm")) {
+ geom_add_curve_parameters(curr_geom, p, end);
}
- else if (line.startswith("end")) {
+ else if (StringRef(p, end).startswith("end")) {
/* End of curve definition, nothing else to do. */
}
else {
- std::cout << "OBJ element not recognized: '" << line << "'" << std::endl;
+ std::cout << "OBJ element not recognized: '" << std::string(p, end) << "'" << std::endl;
}
}
@@ -500,33 +513,33 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
add_default_mtl_library();
}
-static eMTLSyntaxElement mtl_line_start_to_enum(StringRef &line)
+static eMTLSyntaxElement mtl_line_start_to_enum(const char *&p, const char *end)
{
- if (parse_keyword(line, "map_Kd")) {
+ if (parse_keyword(p, end, "map_Kd")) {
return eMTLSyntaxElement::map_Kd;
}
- if (parse_keyword(line, "map_Ks")) {
+ if (parse_keyword(p, end, "map_Ks")) {
return eMTLSyntaxElement::map_Ks;
}
- if (parse_keyword(line, "map_Ns")) {
+ if (parse_keyword(p, end, "map_Ns")) {
return eMTLSyntaxElement::map_Ns;
}
- if (parse_keyword(line, "map_d")) {
+ if (parse_keyword(p, end, "map_d")) {
return eMTLSyntaxElement::map_d;
}
- if (parse_keyword(line, "refl")) {
+ if (parse_keyword(p, end, "refl")) {
return eMTLSyntaxElement::map_refl;
}
- if (parse_keyword(line, "map_refl")) {
+ if (parse_keyword(p, end, "map_refl")) {
return eMTLSyntaxElement::map_refl;
}
- if (parse_keyword(line, "map_Ke")) {
+ if (parse_keyword(p, end, "map_Ke")) {
return eMTLSyntaxElement::map_Ke;
}
- if (parse_keyword(line, "bump")) {
+ if (parse_keyword(p, end, "bump")) {
return eMTLSyntaxElement::map_Bump;
}
- if (parse_keyword(line, "map_Bump") || parse_keyword(line, "map_bump")) {
+ if (parse_keyword(p, end, "map_Bump") || parse_keyword(p, end, "map_bump")) {
return eMTLSyntaxElement::map_Bump;
}
return eMTLSyntaxElement::string;
@@ -544,39 +557,43 @@ static const std::pair<StringRef, int> unsupported_texture_options[] = {
{"-texres", 1},
};
-static bool parse_texture_option(StringRef &line, MTLMaterial *material, tex_map_XX &tex_map)
+static bool parse_texture_option(const char *&p,
+ const char *end,
+ MTLMaterial *material,
+ tex_map_XX &tex_map)
{
- line = drop_whitespace(line);
- if (parse_keyword(line, "-o")) {
- line = parse_floats(line, 0.0f, tex_map.translation, 3);
+ p = drop_whitespace(p, end);
+ if (parse_keyword(p, end, "-o")) {
+ p = parse_floats(p, end, 0.0f, tex_map.translation, 3);
return true;
}
- if (parse_keyword(line, "-s")) {
- line = parse_floats(line, 1.0f, tex_map.scale, 3);
+ if (parse_keyword(p, end, "-s")) {
+ p = parse_floats(p, end, 1.0f, tex_map.scale, 3);
return true;
}
- if (parse_keyword(line, "-bm")) {
- line = parse_float(line, 1.0f, material->map_Bump_strength);
+ if (parse_keyword(p, end, "-bm")) {
+ p = parse_float(p, end, 1.0f, material->map_Bump_strength);
return true;
}
- if (parse_keyword(line, "-type")) {
- line = drop_whitespace(line);
+ if (parse_keyword(p, end, "-type")) {
+ p = drop_whitespace(p, end);
/* Only sphere is supported. */
tex_map.projection_type = SHD_PROJ_SPHERE;
+ const StringRef line = StringRef(p, end);
if (!line.startswith("sphere")) {
std::cerr << "OBJ import: only sphere MTL projection type is supported: '" << line << "'"
<< std::endl;
}
- line = drop_non_whitespace(line);
+ p = drop_non_whitespace(p, end);
return true;
}
/* Check for unsupported options and skip them. */
for (const auto &opt : unsupported_texture_options) {
- if (parse_keyword(line, opt.first)) {
+ if (parse_keyword(p, end, opt.first)) {
/* Drop the arguments. */
for (int i = 0; i < opt.second; ++i) {
- line = drop_whitespace(line);
- line = drop_non_whitespace(line);
+ p = drop_whitespace(p, end);
+ p = drop_non_whitespace(p, end);
}
return true;
}
@@ -585,15 +602,19 @@ static bool parse_texture_option(StringRef &line, MTLMaterial *material, tex_map
return false;
}
-static void parse_texture_map(StringRef line, MTLMaterial *material, const char *mtl_dir_path)
+static void parse_texture_map(const char *p,
+ const char *end,
+ MTLMaterial *material,
+ const char *mtl_dir_path)
{
+ const StringRef line = StringRef(p, end);
bool is_map = line.startswith("map_");
bool is_refl = line.startswith("refl");
bool is_bump = line.startswith("bump");
if (!is_map && !is_refl && !is_bump) {
return;
}
- eMTLSyntaxElement key = mtl_line_start_to_enum(line);
+ eMTLSyntaxElement key = mtl_line_start_to_enum(p, end);
if (key == eMTLSyntaxElement::string || !material->texture_maps.contains(key)) {
/* No supported texture map found. */
std::cerr << "OBJ import: MTL texture map type not supported: '" << line << "'" << std::endl;
@@ -603,12 +624,11 @@ static void parse_texture_map(StringRef line, MTLMaterial *material, const char
tex_map.mtl_dir_path = mtl_dir_path;
/* Parse texture map options. */
- while (parse_texture_option(line, material, tex_map)) {
+ while (parse_texture_option(p, end, material, tex_map)) {
}
/* What remains is the image path. */
- line = line.trim();
- tex_map.image_path = line;
+ tex_map.image_path = StringRef(p, end).trim();
}
Span<std::string> OBJParser::mtl_libraries() const
@@ -666,51 +686,53 @@ void MTLParser::parse_and_store(Map<string, std::unique_ptr<MTLMaterial>> &r_mat
StringRef buffer_str{(const char *)buffer, (int64_t)buffer_len};
while (!buffer_str.is_empty()) {
- StringRef line = read_next_line(buffer_str);
- line = drop_whitespace(line);
- if (line.is_empty()) {
+ const StringRef line = read_next_line(buffer_str);
+ const char *p = line.begin(), *end = line.end();
+ p = drop_whitespace(p, end);
+ if (p == end) {
continue;
}
- if (parse_keyword(line, "newmtl")) {
- line = line.trim();
- if (r_materials.contains(line)) {
+ if (parse_keyword(p, end, "newmtl")) {
+ StringRef mat_name = StringRef(p, end).trim();
+ if (r_materials.contains(mat_name)) {
material = nullptr;
}
else {
- material = r_materials.lookup_or_add(string(line), std::make_unique<MTLMaterial>()).get();
+ material =
+ r_materials.lookup_or_add(string(mat_name), std::make_unique<MTLMaterial>()).get();
}
}
else if (material != nullptr) {
- if (parse_keyword(line, "Ns")) {
- parse_float(line, 324.0f, material->Ns);
+ if (parse_keyword(p, end, "Ns")) {
+ parse_float(p, end, 324.0f, material->Ns);
}
- else if (parse_keyword(line, "Ka")) {
- parse_floats(line, 0.0f, material->Ka, 3);
+ else if (parse_keyword(p, end, "Ka")) {
+ parse_floats(p, end, 0.0f, material->Ka, 3);
}
- else if (parse_keyword(line, "Kd")) {
- parse_floats(line, 0.8f, material->Kd, 3);
+ else if (parse_keyword(p, end, "Kd")) {
+ parse_floats(p, end, 0.8f, material->Kd, 3);
}
- else if (parse_keyword(line, "Ks")) {
- parse_floats(line, 0.5f, material->Ks, 3);
+ else if (parse_keyword(p, end, "Ks")) {
+ parse_floats(p, end, 0.5f, material->Ks, 3);
}
- else if (parse_keyword(line, "Ke")) {
- parse_floats(line, 0.0f, material->Ke, 3);
+ else if (parse_keyword(p, end, "Ke")) {
+ parse_floats(p, end, 0.0f, material->Ke, 3);
}
- else if (parse_keyword(line, "Ni")) {
- parse_float(line, 1.45f, material->Ni);
+ else if (parse_keyword(p, end, "Ni")) {
+ parse_float(p, end, 1.45f, material->Ni);
}
- else if (parse_keyword(line, "d")) {
- parse_float(line, 1.0f, material->d);
+ else if (parse_keyword(p, end, "d")) {
+ parse_float(p, end, 1.0f, material->d);
}
- else if (parse_keyword(line, "illum")) {
+ else if (parse_keyword(p, end, "illum")) {
/* Some files incorrectly use a float (T60135). */
float val;
- parse_float(line, 1.0f, val);
+ parse_float(p, end, 1.0f, val);
material->illum = val;
}
else {
- parse_texture_map(line, material, mtl_dir_path_);
+ parse_texture_map(p, end, material, mtl_dir_path_);
}
}
}