-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathModel.cpp
122 lines (106 loc) · 3.11 KB
/
Model.cpp
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
#include "Model.h"
void Model::Draw(Shader& shader)
{
for (auto mesh : meshes)
{
mesh.Draw(shader);
}
}
void Model::LoadModel(string path)
{
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(path, aiProcess_FlipUVs | aiProcess_Triangulate);
if (scene == nullptr || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
return;
}
directory = path.substr(0, path.find_last_of('/'));
ProcessNode(scene->mRootNode, scene);
}
void Model::ProcessNode(aiNode* node, const aiScene* scene)
{
for (auto i = 0; i < node->mNumMeshes; ++i)
{
auto mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(ProcessMesh(mesh, scene));
}
for (auto i = 0; i < node->mNumChildren; ++i)
{
ProcessNode(node->mChildren[i], scene);
}
}
Mesh Model::ProcessMesh(aiMesh* mesh, const aiScene* scene)
{
vector<Vertex> vertices;
vector<GLuint> indices;
vector<Texture> textures;
//Position
for (auto i = 0; i < mesh->mNumVertices; ++i)
{
Vertex vertex;
glm::vec3 vec(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
vertex.Position = vec;
vec.x = mesh->mNormals[i].x;
vec.y = mesh->mNormals[i].y;
vec.z = mesh->mNormals[i].z;
vertex.Normal = vec;
if (mesh->mTextureCoords[0])
{
vertex.TexCoords = glm::vec2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y);
}
else
{
vertex.TexCoords = glm::vec2(0);
}
vertices.push_back(vertex);
}
//Indices
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
for (unsigned int j = 0; j < face.mNumIndices; j++)
indices.push_back(face.mIndices[j]);
}
//Material
if (mesh->mMaterialIndex >= 0)
{
auto material = scene->mMaterials[mesh->mMaterialIndex];
vector<Texture> diffuseMaps = LoadMaterialTextures(material,
aiTextureType_DIFFUSE, "texture_diffuse", scene);
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
vector<Texture> specularMaps = LoadMaterialTextures(material,
aiTextureType_SPECULAR, "texture_specular", scene);
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
}
return Mesh(vertices, indices, textures);
}
vector<Texture> Model::LoadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName, const aiScene* scene)
{
vector<Texture> textures;
for (auto i = 0; i < mat->GetTextureCount(type); ++i)
{
aiString name;
mat->GetTexture(type, i, &name);
auto toFind = textures_loaded.find(name.C_Str());
if (toFind != textures_loaded.end())
{
textures.push_back(toFind->second);
}
else
{
Texture tex;
auto filePath = StringUtil::Format("%s/%s", directory.c_str(), name.C_Str());
auto aitexture = scene->GetEmbeddedTexture(name.C_Str());
if (aitexture != nullptr)
tex.id = Resource::LoadTextureFromAssImp(aitexture, GL_CLAMP, GL_LINEAR, GL_LINEAR);
else
tex.id = Resource::LoadTexture(filePath.c_str(), GL_REPEAT, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
tex.type = typeName;
tex.Path = name;
textures.push_back(tex);
textures_loaded[name.C_Str()] = tex;
}
}
return textures;
}