.. _program_listing_file_src_Assets_Loaders_ModelLoader.cpp: Program Listing for File ModelLoader.cpp ======================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/Assets/Loaders/ModelLoader.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "Ramus/Assets/Loaders/ModelLoader.hpp" #include "Ramus/Core/Services/Logger.hpp" #include "Ramus/Graphics/Geometry/Mesh.hpp" #include #include #include #include #include namespace ramus { std::shared_ptr ModelLoader::Load(const std::string& path) { Assimp::Importer importer; const aiScene* scene = importer.ReadFile(path , aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_FlipUVs | aiProcess_GenNormals | aiProcess_CalcTangentSpace); if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { Logger::GetRendererLogger()->debug("Assimp Error: Failed to import model @ {}", path); return nullptr; } else if (!scene->HasMeshes()) { Logger::GetRendererLogger()->debug("Assimp Error: Model @ contains no meshes {}", path); return nullptr; } auto model = std::make_shared(); ProcessNode(scene->mRootNode, scene, *model); return model; } void ModelLoader::ProcessNode(aiNode* node, const aiScene* scene, Model& model) { for (unsigned int i = 0; i < node->mNumMeshes; i++) { aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; model.AddMesh(ProcessMesh(mesh, scene)); } for (unsigned int i = 0; i < node->mNumChildren; i++) { ProcessNode(node->mChildren[i], scene, model); } } std::unique_ptr ModelLoader::ProcessMesh(aiMesh* mesh, const aiScene* scene) { std::vector vertices = ExtractVertices(mesh); std::vector indices = ExtractIndices(mesh); return std::make_unique(std::move(vertices), std::move(indices)); } std::vector ModelLoader::ExtractVertices(aiMesh* mesh) { std::vector vertices; vertices.reserve(mesh->mNumVertices); for (uint32_t i = 0; i < mesh->mNumVertices; i++) { Vertex vertex; vertex.position = { mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z }; if (mesh->HasNormals()) vertex.normal = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z }; vertex.texCoords = mesh->mTextureCoords[0] ? glm::vec2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y) : glm::vec2(0.0f); vertices.push_back(vertex); } return vertices; } std::vector ModelLoader::ExtractIndices(aiMesh* mesh) { std::vector indices; indices.reserve(mesh->mNumFaces * 3); for (uint32_t f = 0; f < mesh->mNumFaces; f++) { const aiFace& face = mesh->mFaces[f]; indices.push_back(face.mIndices[0]); indices.push_back(face.mIndices[1]); indices.push_back(face.mIndices[2]); } return indices; } }