2#include "common/maths/Vec.h"
4#include "editor/assets/Assets.h"
5#include "core/os/FileDialogue.h"
7#include <imgui_internal.h>
11 unsigned int Mesh::s_ID = 0;
19 Mesh::Mesh(Vector<Vertex>& verts, Vector<unsigned int>& inds, VertexBufferLayout layout, glm::mat4 modelMatrix,
unsigned int instances)
20 : m_Instances(instances)
28 m_ModelMatrix = modelMatrix;
30 m_Ebo =
new IndexBuffer(m_Indices);
31 m_Vao = VertexArray::Create();
36 Mesh::Mesh(Vector<Vertex>& verts, Vector<unsigned int>& inds,
unsigned int instances)
37 : m_Instances(instances)
51 m_ModelMatrix = glm::mat4(1.0f);
53 m_Ebo =
new IndexBuffer(m_Indices);
54 m_Vao = VertexArray::Create();
59 Mesh::Mesh(
const std::string& file_name,
unsigned int instances)
60 : m_Instances(instances)
68 Mesh::Mesh(
const std::string& file_name, Ptr<Shader> shader,
unsigned int instances)
69 : m_Instances(instances)
74 BindShader(std::move(shader));
78 Mesh::Mesh(Shape& shape,
unsigned int instances)
79 : m_Instances(instances)
84 m_Vertices = shape.GetPositions();
85 m_Indices = shape.GetIndices();
91 m_Ebo =
new IndexBuffer(m_Indices);
92 m_Vao = VertexArray::Create();
97 void Mesh::Update(
const glm::mat4& modelMatrix)
99 m_ModelMatrix = modelMatrix;
102 void Mesh::BindShader(Ref<Shader> shader)
104 if (shader->GetRendererID() == -1)
106 m_VertexShaderPath = m_Shader->GetVertexShaderPath();
107 m_PixelShaderPath = m_Shader->GetPixelShaderPath();
111 m_VertexShaderPath = shader->GetVertexShaderPath();
112 m_PixelShaderPath = shader->GetPixelShaderPath();
116 void Mesh::loadOBJ(
const std::string& file_name)
119 m_Layout.AddFloat(3);
120 m_Layout.AddFloat(2);
121 m_Layout.AddFloat(3);
122 m_Layout.AddFloat(3);
125 Vector<Maths::Vec3> vertex_positions;
126 Vector<Maths::Vec2> vertex_texcoords;
127 Vector<Maths::Vec3> vertex_normals;
130 std::vector<GLint> vertex_position_indicies;
131 std::vector<GLint> vertex_texcoord_indicies;
132 std::vector<GLint> vertex_normal_indicies;
134 std::stringstream ss;
135 std::ifstream in_file(file_name.c_str());
136 std::string line =
"";
137 std::string prefix =
"";
138 Maths::Vec3 temp_vec3;
139 Maths::Vec2 temp_vec2;
140 GLint temp_glint = 0;
143 if (!in_file.is_open())
145 throw "ERROR::OBJLOADER::Could not open file.";
149 while (std::getline(in_file, line))
159 ss >> temp_vec3.x >> temp_vec3.y >> temp_vec3.z;
160 vertex_positions.push_back(temp_vec3);
163 else if (prefix ==
"vt")
165 ss >> temp_vec2.x >> temp_vec2.y;
166 vertex_texcoords.push_back(temp_vec2);
169 else if (prefix ==
"vn")
171 ss >> temp_vec3.x >> temp_vec3.y >> temp_vec3.z;
172 vertex_normals.push_back(temp_vec3);
175 else if (prefix ==
"f")
178 while (ss >> temp_glint)
182 vertex_position_indicies.push_back(temp_glint);
183 else if (counter == 1)
184 vertex_texcoord_indicies.push_back(temp_glint);
185 else if (counter == 2)
186 vertex_normal_indicies.push_back(temp_glint);
189 if (ss.peek() ==
'/')
194 else if (ss.peek() ==
' ')
209 m_Vertices.resize(vertex_position_indicies.size(), Vertex());
210 vertex_texcoord_indicies.resize(vertex_position_indicies.size(), GLint(0));
211 vertex_normal_indicies.resize(vertex_position_indicies.size(), GLint(0));
212 m_Indices.resize(vertex_position_indicies.size(), GLint(0));
217 int size = m_Vertices.size();
218 for (
size_t i = 0; i < size; i++)
220 if (vertex_texcoord_indicies[i] == 0)
222 m_Vertices[i].texcoord = Maths::Vec2(1.0, 0.0);
226 m_Vertices[i].texcoord = vertex_texcoords[vertex_texcoord_indicies[i] - 1];
229 if (vertex_normal_indicies[i] == 0)
231 m_Vertices[i].normal = Maths::Vec3(1.0, 0.0, 0.0);
235 m_Vertices[i].normal = vertex_normals[vertex_normal_indicies[i] - 1];
237 m_Vertices[i].position = vertex_positions[vertex_position_indicies[i] - 1];
241 for (
size_t i = 0; i < size; i += 3)
256 float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
258 tangent = { f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x), f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y), f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z) };
259 m_Vertices[i].tangent = tangent;
260 m_Vertices[i + 1].tangent = tangent;
261 m_Vertices[i + 2].tangent = tangent;
264 m_Ebo =
new IndexBuffer(m_Indices);
265 m_Vao = VertexArray::Create();
267 std::cout <<
"OBJ file loaded!"
273 void Mesh::SetVertices(Vector<Vertex> vertices)
275 for (
int i = 0; i < vertices.size(); i++)
277 m_Vertices[i] = vertices[i];
283 void Mesh::SetIndices(Vector<unsigned int> indices)
285 for (
int i = 0; i < indices.size(); i++)
287 m_Indices[i] = indices[i];
291 void Mesh::Draw(
Camera* camera)
293 if (m_Shader ==
nullptr)
295 std::cout <<
"Shader is not bound to the mesh!" << std::endl;
300 VertexBuffer vbo(m_Vertices);
301 vbo.Bind(m_Vertices);
303 m_Vao->AddVertexBuffer(vbo, m_Layout, m_Vertices);
304 m_Vao->AddIndexBuffer(*m_Ebo);
306 m_Shader->SetUniformMat4f(
"u_Model", m_ModelMatrix);
307 m_Shader->SetUniformMat4f(
"u_View", camera->GetViewMatrix());
308 m_Shader->SetUniformMat4f(
"u_Proj", camera->GetProjectionMatrix());
310 m_Shader->SetUniform1f(
"Shininess", m_Shininess);
311 m_Shader->SetUniform1f(
"AmbientStrength", m_AmbientStrength);
312 m_Shader->SetUniform1f(
"SpecularStrength", m_SpecularStrength);
316 for (
auto texture : m_Textures)
318 if (texture ==
nullptr)
322 texture->Bind(texture->GetRendererID());
324 m_Shader->SetUniform1i(texture->GetName(), texture->GetRendererID());
328 Renderer::Draw(m_Vao, m_Ebo->GetCount(), m_Instances);
331 void Mesh::normalizeVertices()
334 for (
int i = 0; i < m_Vertices.size(); i++)
336 float mag = sqrt(m_Vertices[i].position.x * m_Vertices[i].position.x + m_Vertices[i].position.y * m_Vertices[i].position.y + m_Vertices[i].position.z * m_Vertices[i].position.z);
337 maxMag = std::max(mag, maxMag);
340 for (
int i = 0; i < m_Vertices.size(); i++)
342 m_Vertices[i].position = m_Vertices[i].position * (1 / maxMag);
346 void Mesh::EditMesh()
351 void Mesh::ImGuiRender()
355 ImGui::Begin(
"Mesh Editor");
356 ImGui::PushID(
"MeshEditor" + m_ID);
357 if (ImGui::Button(
"Close Mesh Editor"))
361 ImGui::Text(
"Mesh ID: %d", m_ID);
362 ImGui::Text(
"Vertices: %d", m_Vertices.size());
363 ImGui::Text(
"Indices: %d", m_Indices.size());
364 ImGui::Text(
"Instances: %d", m_Instances);
365 ImGui::SeparatorText(
"Model Matirx");
366 ImGui::InputFloat4(
"##ModelMatrix1", &m_ModelMatrix[0][0]);
367 ImGui::InputFloat4(
"##ModelMatrix2", &m_ModelMatrix[1][0]);
368 ImGui::InputFloat4(
"##ModelMatrix3", &m_ModelMatrix[2][0]);
369 ImGui::InputFloat4(
"##ModelMatrix4", &m_ModelMatrix[3][0]);
371 ImGui::Text(
"Tangents: %d", m_ID);
372 for (
int i = 0; i < m_Vertices.size(); i++)
374 float x = m_Vertices[i].tangent.x;
375 float y = m_Vertices[i].tangent.y;
376 float z = m_Vertices[i].tangent.z;
377 ImGui::Text(
"Tangent %d = (%d, %d, %d)", i, x, y, z);
380 ImGui::SeparatorText(
"Shader");
381 ImGui::Text(
"Vertex Shader");
382 if (!m_VertexShaderPath.empty())
384 ImGui::Text(m_VertexShaderPath.c_str());
388 ImGui::Text(
"No Vertex Shader");
391 ImGui::PushID(
"VertexShader");
392 unsigned int texId = VividGui::Assets::GetInstance()->GetTexOpen()->GetRendererID();
393 if (ImGui::ImageButton((ImTextureID)texId,
394 ImVec2(VividGui::Assets::GetInstance()->GetButtonWidth(), VividGui::Assets::GetInstance()->GetButtonWidth()),
401 std::string file = FileDialogue::OpenFile({}, {});
404 m_VertexShaderPath = file;
409 ImGui::Text(
"Pixel Shader");
410 if (!m_PixelShaderPath.empty())
412 ImGui::Text(m_PixelShaderPath.c_str());
416 ImGui::Text(
"No Pixel Shader");
419 ImGui::PushID(
"PixelShader");
420 if (ImGui::ImageButton((ImTextureID)texId,
421 ImVec2(VividGui::Assets::GetInstance()->GetButtonWidth(), VividGui::Assets::GetInstance()->GetButtonWidth()),
422 { 0, 0 }, { 1, 1 }, 2))
424 std::string file = FileDialogue::OpenFile({}, {});
427 m_PixelShaderPath = file;
432 if (ImGui::Button(
"Compile Shader"))
434 if (!m_VertexShaderPath.empty() && !m_PixelShaderPath.empty())
436 BindShader(Ref<Shader>(
new Shader(m_VertexShaderPath, m_PixelShaderPath)));
442 ImGui::SeparatorText(
"Textures");
445 for (
auto&& texture : m_Textures)
447 if (texture ==
nullptr)
451 ImGui::Text(texture->GetName().c_str());
453 ImGui::Image((ImTextureID)texture->GetRendererID(), ImVec2(100, 100));
455 ImGui::Text(texture->GetFilePath().c_str());
457 ImGui::PushID(texture->GetName().c_str());
460 if (ImGui::ImageButton((ImTextureID)VividGui::Assets::GetInstance()->GetTexOpen()->GetRendererID(),
461 ImVec2(VividGui::Assets::GetInstance()->GetButtonWidth(), VividGui::Assets::GetInstance()->GetButtonWidth()),
462 { 0, 1 }, { 1, 0 }, 2))
464 std::string file = FileDialogue::OpenFile({}, {});
467 String name = texture->GetName();
468 texture = Ref<Texture>(
new Texture(file));
469 texture->SetName(name);
475 ImGui::PushID(std::to_string(slot).c_str());
476 if (ImGui::ImageButton((ImTextureID)VividGui::Assets::GetInstance()->GetTexMinus()->GetRendererID(),
477 ImVec2(VividGui::Assets::GetInstance()->GetButtonWidth(), VividGui::Assets::GetInstance()->GetButtonWidth()),
478 { 0.25, 0.75 }, { 0.75, 0.25 }, 2))
480 m_Textures.erase(m_Textures.begin() + slot);
485 String temp = texture->GetName();
486 char* name = temp.data();
488 static const ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue;
489 String slotName =
"Texture Name##" + std::to_string(slot);
490 if (ImGui::InputText(slotName.c_str(), name, 255, flags))
494 texture->SetName(
"Texture" + std::to_string(slot));
499 for (
int i = 0; i < temp.size(); i++)
506 texture->SetName(name);
509 for (
int i = 0; i < m_Textures.size(); i++)
516 if (m_Textures[i]->GetName() == temp)
518 ImGui::Text(
"Name already exists");
525 ImGui::PushID(
"AddTexture" + m_ID);
526 if (ImGui::ImageButton((ImTextureID)VividGui::Assets::GetInstance()->GetTexPlus()->GetRendererID(),
527 ImVec2(VividGui::Assets::GetInstance()->GetButtonWidth(), VividGui::Assets::GetInstance()->GetButtonWidth()),
528 { 1, 0 }, { 0, 1 }, 2))
530 std::string file = FileDialogue::OpenFile({}, {});
538 ImGui::SeparatorText(
"Object Properties");
539 ImGui::SliderFloat(
"Shininess", &m_Shininess, 0.0f, 32.0f);
540 ImGui::SliderFloat(
"Ambient Strength", &m_AmbientStrength, 0.0f, 1.0f);
541 ImGui::SliderFloat(
"Specular Strength", &m_SpecularStrength, 0.0f, 1.0f);
A class that represents the camera.