diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 2276adc..b62321b 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -418,8 +418,21 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) { read = 1; end_not_reached = (curr != s_end); while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, + 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]; + // NOTE: Don't use powf here, it will absolutely murder precision. - mantissa += static_cast(*curr - 0x30) * pow(10.0, -read); + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : pow(10.0, -read)); read++; curr++; end_not_reached = (curr != s_end); @@ -459,8 +472,8 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) { } assemble: - *result = - (sign == '+' ? 1 : -1) * ldexp(mantissa * pow(5.0, exponent), exponent); + *result = (sign == '+' ? 1 : -1) * + (exponent ? ldexp(mantissa * pow(5.0, exponent), exponent) : mantissa); return true; fail: return false; @@ -692,9 +705,8 @@ void LoadMtl(std::map *material_map, material_t material; InitMaterial(&material); + std::string linebuf; while (inStream->peek() != -1) { - std::string linebuf; - safeGetline(*inStream, linebuf); // Trim trailing whitespace. @@ -1090,8 +1102,8 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, shape_t shape; + std::string linebuf; while (inStream->peek() != -1) { - std::string linebuf; safeGetline(*inStream, linebuf); // Trim newline '\r\n' or '\n'