| 835 | } |
| 836 | |
| 837 | inline std::optional<olc::utils::hw3d::mesh> LoadObj(const std::string& path) |
| 838 | { |
| 839 | olc::utils::hw3d::mesh m; |
| 840 | |
| 841 | std::ifstream ifs(path); |
| 842 | if (!ifs.is_open()) |
| 843 | return std::nullopt; |
| 844 | |
| 845 | std::vector<olc::vf3d> verts; |
| 846 | std::vector<olc::vf3d> norms; |
| 847 | std::vector<olc::vf2d> texs; |
| 848 | std::vector<std::vector<std::vector<int>>> faces; |
| 849 | |
| 850 | std::string sLine; |
| 851 | while (std::getline(ifs, sLine)) |
| 852 | { |
| 853 | std::stringstream s(sLine); |
| 854 | |
| 855 | char junk; |
| 856 | float x, y, z, u, v; |
| 857 | |
| 858 | if (sLine[0] == 'v') |
| 859 | { |
| 860 | if (sLine[1] == 't') |
| 861 | { |
| 862 | // Line is 2D texture coordinate |
| 863 | s >> junk >> junk >> u >> v; |
| 864 | texs.push_back({ u, 1.0f-v }); |
| 865 | } |
| 866 | else if (sLine[1] == 'n') |
| 867 | { |
| 868 | // Line is a 3D normal |
| 869 | s >> junk >> junk >> x >> y >> z; |
| 870 | norms.push_back({ -x, y, z }); |
| 871 | } |
| 872 | else |
| 873 | { |
| 874 | // Line is a 3D vertex |
| 875 | s >> junk >> x >> y >> z; |
| 876 | verts.push_back({ -x, y, z }); |
| 877 | } |
| 878 | } |
| 879 | |
| 880 | if (sLine[0] == 'f') |
| 881 | { |
| 882 | // Line is a Face description. A face may consist of multiple vertices. |
| 883 | std::string sToken; |
| 884 | std::vector<std::string> vTuples; |
| 885 | s >> junk; while (s >> sToken) vTuples.push_back(sToken); |
| 886 | |
| 887 | std::vector<std::vector<int>> face; |
| 888 | for (const auto& d : vTuples) |
| 889 | { |
| 890 | std::vector<int> indices; |
| 891 | std::string temp; |
| 892 | for (const auto c : d) |
| 893 | { |
| 894 | if (c == ' ' || c == '/') |