Final Year Project
Loading...
Searching...
No Matches
ModelLoading.cpp
1#pragma once
2#include <stdafx.h>
3#include <ModelLoading.h>
4#include <glm/gtc/type_ptr.hpp>
5#include <variant>
6#include "Vertex.h"
7#include "Mesh.h"
8#include "IO.h"
9#include <Model.h>
10
11namespace fpr
12{
13uint32_t ModelLoader::mesh_index = 0;
14ModelPrimitives ModelLoader::LoadModelAssimp(const char* file_name)
15{
16 //Load model data and parse it using assimp.
17 std::string_view file_name_sv(file_name);
18 Assimp::Importer importer;
19 const aiScene* scene = importer.ReadFile(file_name, USING_ASSIMP_DEFAULT_FLAGS);
20
21 if(!scene)
22 std::cout << "Failed to load scene:\t" << file_name << '\n';
23 size_t last_slash_pos = file_name_sv.rfind("/") + 1; //+1 to include the "/"
24 std::string file_directory(file_name_sv.substr(0, last_slash_pos));
25 ModelPrimitives data;
26
27 data.meshes.reserve(scene->mNumMeshes);
28 //Iterate over the meshes in the model.
29 for(size_t mesh = 0; mesh < scene->mNumMeshes; ++mesh)
30 {
31 std::vector<fpr::Vertex> mesh_vertices;
32 std::vector<uint32_t> mesh_indices;
33 aiMesh* current_mesh = scene->mMeshes[mesh];
34
35 aiMaterial* material = scene->mMaterials[current_mesh->mMaterialIndex];
36 bool using_normals = current_mesh->HasNormals();
37
38 //Potential materials to be used.
39 aiString albedo_path;
40 aiString metal;
41 aiString ao;
42 aiString normal;
43 aiString bump;
44 aiString roughness;
45
46
47 //Output the available materials, mostly for debugging purposes.
48 for(auto& [name, type] : ASSIMP_TEXTURE_TYPES)
49 {
50 aiString mat_name;
51 if(material->GetTexture(type, 0, &mat_name) == aiReturn_SUCCESS)
52 printf("%s\t %s\n", name, mat_name.C_Str());
53 }
54
55 //Store diffuse map.
56 material->GetTexture(aiTextureType_DIFFUSE, 0, &albedo_path);
57
58 std::string full_albedo_path(file_directory);
59 full_albedo_path.append(albedo_path.C_Str());
60
61 //Store primitves, such as UVs, vertices, normals and tangents.
62 for(size_t vert = 0; vert < current_mesh->mNumVertices; ++vert)
63 {
64 fpr::Vertex vertex;
65 vertex.position.x = current_mesh->mVertices[vert].x;
66 vertex.position.y = current_mesh->mVertices[vert].y;
67 vertex.position.z = current_mesh->mVertices[vert].z;
68
69 if(current_mesh->HasTextureCoords(0))
70 {
71 vertex.uv.x = current_mesh->mTextureCoords[0][vert].x;
72 vertex.uv.y = current_mesh->mTextureCoords[0][vert].y;
73 }
74
75 if(using_normals)
76 {
77 vertex.normal.x = current_mesh->mNormals[vert].x;
78 vertex.normal.y = current_mesh->mNormals[vert].y;
79 vertex.normal.z = current_mesh->mNormals[vert].z;
80 }
81 if(current_mesh->HasTangentsAndBitangents())
82 {
83 vertex.tangent.x = current_mesh->mTangents[vert].x;
84 vertex.tangent.y = current_mesh->mTangents[vert].y;
85 vertex.tangent.z = current_mesh->mTangents[vert].z;
86 }
87 mesh_vertices.push_back(vertex);
88 }
89
90
91 for(size_t face = 0; face < current_mesh->mNumFaces; ++face)
92 {
93 aiFace* current_face = &current_mesh->mFaces[face];
94
95 mesh_indices.push_back(current_face->mIndices[0]);
96 mesh_indices.push_back(current_face->mIndices[1]);
97 mesh_indices.push_back(current_face->mIndices[2]);
98 }
99
100 data.indices.insert(std::end(data.indices), std::begin(mesh_indices), std::end(mesh_indices));
101 data.vertices.insert(std::end(data.vertices), std::begin(mesh_vertices), std::end(mesh_vertices));
102
103 vk::DeviceSize index_offset = data.indices.size() - mesh_indices.size();
104 vk::DeviceSize vertex_offset = sizeof Vertex * data.vertices.size() - sizeof Vertex * mesh_vertices.size();
105
106 data.meshes.emplace_back(
107 mesh_index,
108 (vk::DeviceSize)index_offset,
109 (uint32_t)mesh_indices.size(),
110 vertex_offset,
111 (uint32_t)mesh_vertices.size(),
112 full_albedo_path);
113 mesh_index++;
114 }
115 return data;
116}
117} // namespace fpr