Реши ошибку с загрузкой MTL.
Загрузка модели из файла: D:\!Projects\Windows\Our-project-OpenGL-Engine\x64\Debug\..\..\models\sponza.obj
OBJ файл успешно загружен.
Триангуляция завершена.
Количество материалов: 0
Ошибка: не удалось загрузить материалы из MTL файла.
Количество шейпов: 393

#include "Model.hpp"
#include <filesystem>
#include <unordered_map>
#include "LightWinAPI.hpp"
#include "rapidobj/rapidobj.hpp"

Model::Model(const std::string& filepath) {
    loadModel(filepath);
}

void Model::loadModel(const std::string& filepath) {
    std::string baseDir = filepath.substr(0, filepath.find_last_of("/\\") + 1);
    std::cout << "Загрузка модели из файла: " << filepath << std::endl;

    // Явная загрузка библиотеки материалов
    rapidobj::MaterialLibrary matLibrary = rapidobj::MaterialLibrary::SearchPath(baseDir, rapidobj::Load::Optional);
    rapidobj::Result result = rapidobj::ParseFile(filepath, matLibrary);
    if (result.error) {
        std::cerr << "Ошибка парсинга файла OBJ: " << result.error.code.message() << '\n';
        return;
    }
    std::cout << "OBJ файл успешно загружен." << std::endl;

    // Триангуляция меша
    if (!rapidobj::Triangulate(result)) {
        std::cerr << "Ошибка триангуляции: " << result.error.code.message() << '\n';
        return;
    }
    std::cout << "Триангуляция завершена." << std::endl;

    // Загрузка материалов
    materials.clear();
    std::cout << "Количество материалов: " << result.materials.size() << std::endl;

    if (result.materials.empty()) {
        std::cerr << "Ошибка: не удалось загрузить материалы из MTL файла." << std::endl;
    }

    for (const auto& mat : result.materials) {
        auto material = std::make_shared<Material>();
        material->name = mat.name;
        std::cout << "Загрузка материала: " << mat.name << std::endl;

        material->ambient = glm::vec3(mat.ambient[0], mat.ambient[1], mat.ambient[2]);
        material->diffuse = glm::vec3(mat.diffuse[0], mat.diffuse[1], mat.diffuse[2]);
        material->shininess = mat.shininess;

        // Загрузка текстур, если они указаны
        if (!mat.diffuse_texname.empty()) {
            std::string albedoPath = baseDir + mat.diffuse_texname;
            std::cout << "Путь к текстуре альбедо: " << albedoPath << std::endl;
            if (std::filesystem::exists(albedoPath)) {
                material->albedo = std::make_shared<Texture>(albedoPath, true);
                std::cout << "Текстура альбедо успешно загружена." << std::endl;
            }
            else {
                std::cerr << "Ошибка: текстура альбедо не найдена по пути: " << albedoPath << std::endl;
            }
        }
        else {
            std::cout << "Материал не содержит текстуры альбедо." << std::endl;
        }

        materials.push_back(material);
    }

    // Парсинг шейпов и создание мешей
    meshes.clear();
    std::cout << "Количество шейпов: " << result.shapes.size() << std::endl;
    for (const auto& shape : result.shapes) {
        std::vector<Vertex> vertices;
        std::vector<unsigned int> indices;
        int materialID = shape.mesh.material_ids.empty() ? -1 : shape.mesh.material_ids[0];

        std::unordered_map<Vertex, unsigned int> uniqueVertices;

        // Сбор вершин и индексов из формы
        for (const auto& index : shape.mesh.indices) {
            Vertex vertex;

            // Позиции вершин
            vertex.position = {
                result.attributes.positions[3 * index.position_index + 0],
                result.attributes.positions[3 * index.position_index + 1],
                result.attributes.positions[3 * index.position_index + 2]
            };

            // Нормали (если они указаны)
            if (index.normal_index >= 0) {
                vertex.normal = {
                    result.attributes.normals[3 * index.normal_index + 0],
                    result.attributes.normals[3 * index.normal_index + 1],
                    result.attributes.normals[3 * index.normal_index + 2]
                };
            }
            else {
                vertex.normal = glm::vec3(0.0f, 0.0f, 0.0f);
            }

            // Текстурные координаты (если они указаны)
            if (index.texcoord_index >= 0) {
                vertex.texcoord = {
                    result.attributes.texcoords[2 * index.texcoord_index + 0],
                    1.0f - result.attributes.texcoords[2 * index.texcoord_index + 1]
                };
            }
            else {
                vertex.texcoord = glm::vec2(0.0f, 0.0f);
            }

            // Проверка на уникальность вершины
            if (uniqueVertices.count(vertex) == 0) {
                uniqueVertices[vertex] = static_cast<unsigned int>(vertices.size());
                vertices.push_back(vertex);
            }

            indices.push_back(uniqueVertices[vertex]);
        }

        // Создание меша
        auto mesh = std::make_unique<GLMesh>(vertices.data(), static_cast<GLsizei>(vertices.size()),
            indices.data(), static_cast<GLsizei>(indices.size()));

        // Назначение материала мешу, если материал существует
        if (materialID >= 0 && materialID < static_cast<int>(materials.size())) {
            std::cout << "Назначение материала ID " << materialID << " мешу." << std::endl;
            mesh->setMaterial(materials[materialID]);
        }
        else {
            std::cerr << "Ошибка: материал с ID " << materialID << " не найден." << std::endl;
        }

        meshes.push_back(std::move(mesh));
    }
    std::cout << "Загрузка модели завершена." << std::endl;
}