-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtextured_model_loading.cpp
More file actions
125 lines (100 loc) · 5.02 KB
/
textured_model_loading.cpp
File metadata and controls
125 lines (100 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <spdlog/spdlog.h>
#include "assimp/Importer.hpp"
#include "assimp/postprocess.h"
#include "textured_model_loading.hpp"
#include "sbpt_generated_includes.hpp"
/**
* @brief returns a list of lists of the form specified by \ref get_ordered_vertex_positions
*
* @return as mentioned in brief
*/
std::vector<std::vector<glm::vec3>> TexturedModel::get_ordered_vertex_positions_for_each_mesh() {
std::vector<std::vector<glm::vec3>> ovpfem;
for (auto &mesh : meshes) {
ovpfem.push_back(get_ordered_vertex_positions(mesh.vertex_positions, mesh.indices));
}
return ovpfem;
}
TexturedModel TexturedModelLoader::load_model(const std::string &path) {
// because we may load multiple models, remember to clear out the old data.
this->recursively_collected_meshes.clear();
auto process_step = [this](aiMesh *mesh, const aiScene *scene) {
this->recursively_collected_meshes.push_back(process_mesh(mesh, scene));
};
auto recursively_process_nodes = this->recursively_process_nodes_closure(process_step);
this->call_function_with_assimp_importer_context(path, [&](auto root, auto scene) {
spdlog::get(Systems::asset_loading)->info("starting to process nodes");
recursively_process_nodes(scene->mRootNode, scene);
spdlog::get(Systems::asset_loading)->info("processed all nodes");
});
return {this->recursively_collected_meshes};
};
TexturedMesh TexturedModelLoader::process_mesh(aiMesh *mesh, const aiScene *scene) {
Mesh processed_mesh = ModelLoader::process_mesh(mesh, scene);
auto [texture_coordinates, normals] = process_mesh_vertices_texture_info(mesh);
auto used_textures = process_mesh_materials(mesh, scene);
return TexturedMesh(processed_mesh.vertex_positions, processed_mesh.indices, texture_coordinates, normals,
used_textures);
};
/**
*
* /param mesh
* /return a tuple such that the first component is a list of texture coordinates for each vertex as per the order
* generated by process_mesh of the base class, normals are in the second component in the same format
*/
std::pair<std::vector<glm::vec2>, std::vector<glm::vec3>>
TexturedModelLoader::process_mesh_vertices_texture_info(aiMesh *mesh) {
std::vector<glm::vec2> texture_coordinates;
std::vector<glm::vec3> normals;
bool mesh_has_texture_coordinates = mesh->mTextureCoords[0] != nullptr;
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
normals.push_back(assimp_to_glm_3d_vector(mesh->mNormals[i]));
glm::vec2 texture_coordinate;
if (mesh_has_texture_coordinates) {
texture_coordinate = glm::vec2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y);
} else {
spdlog::get(Systems::asset_loading)->warn("This mesh doesn't have texture coordinates!");
texture_coordinate = glm::vec2(0.0f, 0.0f);
}
texture_coordinates.push_back(texture_coordinate);
}
return {texture_coordinates, normals};
}
std::vector<TextureInfo> TexturedModelLoader::process_mesh_materials(aiMesh *mesh, const aiScene *scene) {
std::vector<TextureInfo> textures;
bool mesh_has_materials = mesh->mMaterialIndex >= 0;
if (mesh_has_materials) {
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
std::vector<TextureInfo> diffuse_maps_texture_info =
get_texture_info_for_material(material, aiTextureType_DIFFUSE, TextureType::DIFFUSE);
textures.insert(textures.end(), diffuse_maps_texture_info.begin(), diffuse_maps_texture_info.end());
if (diffuse_maps_texture_info.size() == 0) {
spdlog::get(Systems::asset_loading)->warn("This material doesn't have any diffuse maps");
}
std::vector<TextureInfo> specular_maps_texture_info =
get_texture_info_for_material(material, aiTextureType_SPECULAR, TextureType::SPECULAR);
textures.insert(textures.end(), specular_maps_texture_info.begin(), specular_maps_texture_info.end());
if (specular_maps_texture_info.size() == 0) {
spdlog::get(Systems::asset_loading)->info("This material doesn't have any specular maps");
}
}
return textures;
}
/**
* /param material is a collection of all assets required to make a surface have certain lighting effects
* /param type the type of the texture using assimps enum
* /param texture_type the type of the texture using our own enum
* /return
*/
std::vector<TextureInfo> TexturedModelLoader::get_texture_info_for_material(aiMaterial *material, aiTextureType type,
TextureType texture_type) {
std::vector<TextureInfo> textures;
for (unsigned int i = 0; i < material->GetTextureCount(type); i++) {
aiString texture_path;
material->GetTexture(type, i, &texture_path);
std::string asset_path = directory_to_asset_being_loaded + std::string(texture_path.C_Str());
TextureInfo texture{texture_type, asset_path.c_str()};
textures.push_back(texture);
}
return textures;
};