diff --git a/include/blt/gfx/loader/obj_loader.h b/include/blt/gfx/loader/obj_loader.h index 1e5beb6..0ea3f3b 100644 --- a/include/blt/gfx/loader/obj_loader.h +++ b/include/blt/gfx/loader/obj_loader.h @@ -85,23 +85,26 @@ namespace blt::gfx }; }; + class char_tokenizer; + class obj_loader { private: std::vector vertices; std::vector uvs; std::vector normals; + + // maps between vertex indices -> face (constructed vertex) + HASHMAP vertex_data; struct object_data { std::string object_name; - // maps between vertex indices -> face (constructed vertex) - HASHMAP vertex_data; std::vector indices; }; - + std::vector data; private: + void parse_extra_line(char_tokenizer& tokenizer); void parse_face(std::string_view line); - public: void parseFile(std::string_view file); }; diff --git a/libraries/BLT b/libraries/BLT index 903bac9..9147a85 160000 --- a/libraries/BLT +++ b/libraries/BLT @@ -1 +1 @@ -Subproject commit 903bac9fc10e48005d68a0f9e9d060de538e898c +Subproject commit 9147a85dc32f06be2a4cfe4e422fdbc52679adc5 diff --git a/src/blt/gfx/loader/obj_loader.cpp b/src/blt/gfx/loader/obj_loader.cpp index ee3b36c..30a0a41 100644 --- a/src/blt/gfx/loader/obj_loader.cpp +++ b/src/blt/gfx/loader/obj_loader.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include namespace blt::gfx { @@ -31,22 +33,94 @@ namespace blt::gfx explicit char_tokenizer(std::string_view view): string(view) {} - char peek() + inline char peek() { return string[current_pos]; } - char advance() + inline char advance() { return string[current_pos++]; } - bool has_next(size_t offset = 0) + inline bool has_next(size_t offset = 0) { return current_pos + offset < string.size(); } + + inline std::string_view read_fully() + { + return blt::string::trim(string.substr(current_pos)); + } }; + float get(std::string_view str) + { + float x; + const auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), x); + // probably not needed. + if (ec != std::errc()) + { +// int i; +// const auto [ptr2, ec2] = std::from_chars(str.data(), str.data() + str.size(), i); +// if (ec2 == std::errc()) +// { +// x = static_cast(i); +// } else +// { + BLT_WARN("Unable to parse string '%s' into number!", std::string(str).c_str()); + x = 0; +// } + } + return x; + } + + void obj_loader::parse_extra_line(char_tokenizer& tokenizer) + { + char type = tokenizer.advance(); + auto elements = blt::string::split(std::string(tokenizer.read_fully()), " "); + if (elements.size() < 2) + { + BLT_ERROR("Unable to parse line '%s' too few arguments to type '%c'", std::string(tokenizer.read_fully()).c_str(), type); + return; + } + float x = get(elements[0]), y = get(elements[1]); + if (std::isspace(type)) + { + if (elements.size() < 3) + { + BLT_ERROR("Unable to parse line '%s' too few arguments to type '%c'", std::string(tokenizer.read_fully()).c_str(), type); + return; + } + float z = get(elements[2]); + vertices.push_back(vertex_t{x, y, z}); + return; + } + switch (type) + { + case 't': + uvs.push_back(uv_t{x,y}); + break; + case 'n': + { + if (elements.size() < 3) + { + BLT_ERROR("Unable to parse line '%s' too few arguments to type '%c'", std::string(tokenizer.read_fully()).c_str(), type); + return; + } + float z = get(elements[2]); + normals.push_back(vertex_t{x, y, z}); + break; + } + case 'p': + // optional todo + break; + default: + BLT_WARN("Unexpected type '%c'", type); + break; + } + } + std::vector quick_load(std::string_view file) { std::vector objects; @@ -61,8 +135,7 @@ namespace blt::gfx for (const auto& line : lines) { char_tokenizer token(line); - // line is empty? - if (!token.has_next()) + if (!token.has_next() || token.read_fully().empty()) continue; switch (token.advance()) { @@ -75,7 +148,7 @@ namespace blt::gfx } case 'v': { - + parse_extra_line(token); break; } case 'o':