Elevate Engine 1
Loading...
Searching...
No Matches
Model.cpp
Go to the documentation of this file.
1#include "eepch.h"
2
3#include "Model.h"
4
5#include <glm/glm.hpp>
11
12#include <filesystem>
13
15{
16 switch (texture->GetUsage())
17 {
18 case Elevate::TextureType::Diffuse: return "diffuseTex";
19 case Elevate::TextureType::Specular: return "specularTex";
20 case Elevate::TextureType::Ambient: return "ambientText";
21 case Elevate::TextureType::Normal: return "normalTex";
22 default: return "";
23 }
24}
25
27{
28 switch (type)
29 {
31 m_batchedMesh = Mesh::GenerateCube(1.0f);
32 break;
34 m_batchedMesh = Mesh::GenerateUVSphere(1.0f, 36, 18);
35 break;
41 m_batchedMesh = Mesh::GeneratePlane(1.0f, 1);
42 break;
44 m_batchedMesh = Mesh::GenerateQuad(1.0f);
45 break;
47 default:
48 EE_CORE_ASSERT(false, "Unsupported primitive shape given for mesh creation.");
49 break;
50 }
51}
52
53Elevate::Model::Model(std::string path, MaterialPtr material)
54{
55 // todo : add a macro or const expression for the default value in asset maangers
56 SetMaterial(material ? material : MaterialRegistry::GetMaterial(EE_DEFAULT_MATERIAL));
57
58 if (!path.empty())
59 {
60 LoadModel(path);
61 }
62}
63
64void Elevate::Model::LoadModel(std::string path)
65{
66 std::string resolvedPath = PathResolver::Resolve(path);
67 // Importing the scene
68 Assimp::Importer import;
69 const aiScene* scene = import.ReadFile(resolvedPath, aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_OptimizeMeshes | aiProcess_ImproveCacheLocality);
70
71 // checking and exception catcher
72 if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
73 {
74 EE_CORE_ERROR("ASSIMP LOADING ERROR : {}", import.GetErrorString());
75 return;
76 }
77 m_Directory = resolvedPath.substr(0, resolvedPath.find_last_of('/')); // Used to get the textures afterward
78
79 // Recursive method to process all the nodes in the model
80 MeshData data;
81 std::vector<Mesh> meshes;
82 std::filesystem::path fsPath(resolvedPath);
83 ProcessNode(fsPath.parent_path().string(), scene->mRootNode, scene, data);
84
85 m_batchedMesh = Mesh(data);
86 for (auto& tex : m_batchedMesh.GetTextures())
87 {
88 m_material->SetTexture(GetUniformNameByType(tex), tex);
89 }
90}
91
92void Elevate::Model::ProcessNode(std::string basePath, aiNode* node, const aiScene* scene, MeshData& data)
93{
94 // process all the node's MESHES (if any)
95 for (unsigned int i = 0; i < node->mNumMeshes; i++)
96 {
97 aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
98 ProcessMesh(basePath, mesh, scene, data);
99 }
100 // then do the same for each of its CHILDREN(S)
101 for (unsigned int i = 0; i < node->mNumChildren; i++)
102 {
103 ProcessNode(basePath, node->mChildren[i], scene, data); // Continue till we run out of childrens
104 }
105}
106
107void Elevate::Model::ProcessMesh(std::string basePath, aiMesh* mesh, const aiScene* scene, MeshData& data)
108{
109 uint32_t offset = (uint32_t) data.Vertices.size();
110
111 // Process vertices
112 for (unsigned int i = 0; i < mesh->mNumVertices; i++)
113 {
114 Vertex vertex;
115 ExtractMeshVertex(mesh, vertex, i);
116 data.Vertices.emplace_back(vertex);
117 }
118
119 // process indices
120 for (unsigned int i = 0; i < mesh->mNumFaces; i++)
121 {
122 aiFace face = mesh->mFaces[i];
123 for (unsigned int j = 0; j < face.mNumIndices; j++)
124 {
125 data.Indices.emplace_back(face.mIndices[j] + offset);
126 }
127 }
128
129 // process material
130 if (mesh->mMaterialIndex >= 0)
131 {
132 aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
133 LoadMaterialTextures(basePath, material, aiTextureType_DIFFUSE, TextureType::Diffuse, data);
134 LoadMaterialTextures(basePath, material, aiTextureType_SPECULAR, TextureType::Specular, data);
135 LoadMaterialTextures(basePath, material, aiTextureType_AMBIENT, TextureType::Ambient, data);
136 LoadMaterialTextures(basePath, material, aiTextureType_AMBIENT_OCCLUSION, TextureType::Ambient, data); // todo create new texturetype
137 // todo : load all of the other texture types
138 }
139}
140
141void Elevate::Model::ExtractMeshVertex(aiMesh* mesh, Vertex& vertex, int i)
142{
143 // process vertex positions, normals and texture coordinates
144 glm::vec3 vector;
145 vector.x = mesh->mVertices[i].x;
146 vector.y = mesh->mVertices[i].y;
147 vector.z = mesh->mVertices[i].z;
148 vertex.Position = vector;
149
150 vector.x = mesh->mNormals[i].x;
151 vector.y = mesh->mNormals[i].y;
152 vector.z = mesh->mNormals[i].z;
153 vertex.Normal = vector;
154
155 if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
156 {
157 // text coords
158 glm::vec2 coords;
159 coords.x = mesh->mTextureCoords[0][i].x;
160 coords.y = mesh->mTextureCoords[0][i].y;
161 vertex.TexCoords = coords;
162 }
163
164 if (mesh->mTangents)
165 {
166 // tangent
167 vector.x = mesh->mTangents[i].x;
168 vector.y = mesh->mTangents[i].y;
169 vector.z = mesh->mTangents[i].z;
170 vertex.Tangent = vector;
171 }
172
173 if (mesh->mBitangents)
174 {
175 // bitangent
176 vector.x = mesh->mBitangents[i].x;
177 vector.y = mesh->mBitangents[i].y;
178 vector.z = mesh->mBitangents[i].z;
179 vertex.Bitangent = vector;
180 }
181}
182
183void Elevate::Model::LoadMaterialTextures(std::string basePath, aiMaterial* mat, aiTextureType type, TextureType texType, MeshData& data)
184{
185 for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
186 {
187 aiString str;
188 mat->GetTexture(type, i, &str);
189
190 std::filesystem::path directory(basePath);
191 directory.append(str.C_Str());
192 std::string path = directory.string();
193
194 bool skip = false;
195 for (TexturePtr tex : data.Textures)
196 {
197 if (tex->MatchesPath(path))
198 {
199 skip = true;
200 break;
201 }
202 }
203
204 if (!skip)
205 {
206 data.Textures.emplace_back(Texture::CreateFromFile(path, texType));
207 }
208 }
209}
210
212{
213 Renderer::SubmitMesh(m_batchedMesh.GetVertexArray(), m_material, gameObject->GetModelMatrix(), RenderBucket::GBuffer);
214}
#define EE_DEFAULT_MATERIAL
Definition Material.h:17
std::string GetUniformNameByType(Elevate::TexturePtr texture)
Definition Model.cpp:14
static MaterialPtr GetMaterial(MaterialID id)
Definition Material.cpp:117
static Mesh GeneratePlane(float size, int resolution)
Definition Mesh.cpp:191
static Mesh GenerateUVSphere(float radius, int latitudes, int longitudes)
Definition Mesh.cpp:127
static Mesh GenerateQuad(float size=1.0f)
Definition Mesh.cpp:186
static Mesh GenerateCube(float size=1.0f)
Definition Mesh.cpp:54
void Render() override
Definition Model.cpp:211
Model()=default
static std::string Resolve(const std::string &virtualPath)
static void SubmitMesh(const std::shared_ptr< VertexArray > &vao, const std::shared_ptr< Material > &material, const glm::mat4 &transform, RenderBucket::Type bucketType=RenderBucket::Opaque)
Definition Renderer.cpp:139
static TexturePtr CreateFromFile(const std::string &path, TextureType usage=TextureType::Diffuse)
Definition Texture.cpp:22
std::shared_ptr< Material > MaterialPtr
Definition Material.h:24
TextureType
Definition Texture.h:29
PrimitiveType
Definition Mesh.h:28
std::shared_ptr< Texture > TexturePtr
Definition Texture.h:13