From 4b347824525fc12142494d90a37f0c1da8be7f75 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sun, 25 Jul 2021 15:08:36 -0400 Subject: [PATCH] UI added hover styling and code cleanup --- Editor/Editor.cpp | 37 +++++- Editor/resources/Interface/Editor.css | 106 +++++++++++++++++ Editor/resources/Interface/Editor.interface | 74 ++++++++++++ Editor/resources/Interface/Testing.css | 5 + Editor/resources/Interface/Testing.interface | 8 +- Editor/resources/Shaders/ui.shader | 20 +++- Editor/src/EditorInterface.cpp | 27 +---- Editor/src/FileSystemUI.cpp | 2 +- Editor/src/NewEditor.cpp | 110 ++++++++++++++++++ Editor/src/NewEditor.h | 31 +++++ Nuake/Engine.cpp | 34 +++--- Nuake/PrefabComponent.h | 12 +- Nuake/src/Core/Input.cpp | 9 +- Nuake/src/Rendering/Textures/Texture.h | 2 +- Nuake/src/Resource/Prefab.h | 34 +++--- .../src/Scene/Components/LuaScriptComponent.h | 2 +- Nuake/src/Scene/Components/MeshComponent.cpp | 12 +- .../src/Scene/Components/TransformComponent.h | 4 + Nuake/src/Scene/EditorCamera.cpp | 9 +- Nuake/src/Scene/Scene.cpp | 15 ++- Nuake/src/Scene/Systems/TransformSystem.cpp | 38 ++++-- Nuake/src/UI/Font/FontLoader.h | 1 - Nuake/src/UI/InterfaceParser.cpp | 6 + Nuake/src/UI/Nodes/Node.h | 63 +++++++--- Nuake/src/UI/UserInterface.cpp | 49 ++++++-- Nuake/src/UI/UserInterface.h | 7 +- 26 files changed, 589 insertions(+), 128 deletions(-) create mode 100644 Editor/resources/Interface/Editor.css create mode 100644 Editor/resources/Interface/Editor.interface create mode 100644 Editor/src/NewEditor.cpp create mode 100644 Editor/src/NewEditor.h diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 82328796..7bece5e2 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -18,6 +18,31 @@ #include #include #include "src/UI/UserInterface.h" +#include "src/NewEditor.h" + +void OpenProject() +{ + // Parse the project and load it. + std::string projectPath = Nuake::FileDialog::OpenFile(".project"); + + Nuake::FileSystem::SetRootDirectory(projectPath + "/../"); + Ref project = Nuake::Project::New(); + if (!project->Deserialize(Nuake::FileSystem::ReadFile(projectPath, true))) + { + Nuake::Logger::Log("Error loading project: " + projectPath, Nuake::CRITICAL); + return; + } + + project->FullPath = projectPath; + Nuake::Engine::LoadProject(project); + + // Create new interface named test. + //userInterface = UI::UserInterface::New("test"); + + + // Set current interface running. + //Engine::GetCurrentScene()->AddInterface(userInterface); +} int main() { @@ -30,18 +55,17 @@ int main() Ref lightTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Light.png"); Ref camTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Camera.png"); Ref GuizmoShader = Nuake::ShaderManager::GetShader("resources/Shaders/gizmo.shader"); - Ref uinterface = Nuake::UI::UserInterface::New("Editor", "resources/Interface/Testing.interface"); + + Nuake::NewEditor newEditor = Nuake::NewEditor(); while (!Nuake::Engine::GetCurrentWindow()->ShouldClose()) { Nuake::RenderCommand::Clear(); Nuake::Engine::Tick(); - uinterface->Update(0.0f); Nuake::Engine::Draw(); - if (Nuake::Input::IsKeyPressed(GLFW_KEY_F1)) - uinterface->Reload(); + //newEditor.Update(0.f); if (Nuake::Input::IsKeyPressed(GLFW_KEY_F8)) Nuake::Engine::ExitPlayMode(); @@ -49,7 +73,8 @@ int main() Nuake::Vector2 WindowSize = Nuake::Engine::GetCurrentWindow()->GetSize(); glViewport(0, 0, WindowSize.x, WindowSize.y); Nuake::Renderer2D::BeginDraw(WindowSize); - uinterface->Draw(WindowSize); + + //newEditor.Draw(WindowSize); Ref sceneFramebuffer = Nuake::Engine::GetCurrentWindow()->GetFrameBuffer(); sceneFramebuffer->Bind(); @@ -95,7 +120,7 @@ int main() } sceneFramebuffer->Unbind(); - //editor.Draw(); + editor.Draw(); Nuake::Engine::EndDraw(); } diff --git a/Editor/resources/Interface/Editor.css b/Editor/resources/Interface/Editor.css new file mode 100644 index 00000000..fb595540 --- /dev/null +++ b/Editor/resources/Interface/Editor.css @@ -0,0 +1,106 @@ +.screen { + display: flex; + flex-direction: row; + align-content: flex-start; + justify-content: flex-start; + height: 100%; + width: 100%; +} + +.bottom { + width: 100%; + height: 30px; + background-color: 25 25 25 255; +} + +.toolbar { + width: 100%; + height: 50px; + background-color: 25 25 25 255; + flex-direction: row; + align-content: center; +} + +.toolbar-group-left { + width: 50%; + height: 50px; + background-color: 25 25 25 255; + flex-direction: row; + align-content: center; + justify-content: flex-start; +} + +.component-view { + margin: 0px 0px 0px 16px; +} + +.splitter:hover { + background-color: 128 0 0 255; +} + +.toolbar-group-right { + width: 50%; + height: 50px; + background-color: 25 25 25 255; + flex-direction: row; + align-content: center; + justify-content: flex-end; +} + +.toolbar-button { + height: 42px; + width: 42px; + background-color: 255 25 25 255; + margin: 0px 4px 0px 0px; +} + +.viewport { + width: 20%; + height: 100%; + background-color: 12 12 12 255; +} + +.viewport-tool-bar { + margin: 8px 8px 8px 8px; + flex-direction: row; + width: 100%; +} + +.viewport-tool-test { + background-color: 25 25 25 255; + height: 25px; + width: 100px; + margin: 0px 8px; + align-content: center; +} + +.inspector { + width: 20%; + height: 100%; + min-width: 100px; + flex-direction: column; + padding: 8px 8px 8px 8px; +} + +.middle { + width: 100%; + height: 80%; +} + +.action-menu { + background-color: 25 25 25 255; +} + +.action-menu-item { + margin: 0px 8px 0px 2px; + width: 60px; + height: 100%; + + justify-content: flex-start; + align-content: center; +} + +.action-menu-item:hover { + + background-color: 255 0 0 255; +} \ No newline at end of file diff --git a/Editor/resources/Interface/Editor.interface b/Editor/resources/Interface/Editor.interface new file mode 100644 index 00000000..43d2d058 --- /dev/null +++ b/Editor/resources/Interface/Editor.interface @@ -0,0 +1,74 @@ + + + +

File

+
+ +

Edit

+
+
+ + + +

mous

+
+ +

move

+
+ +

turn

+
+ +

scal

+
+
+ + +

Play

+
+ +

Stop

+
+
+
+ + + + + + + + + + + + +

Transform component

+
+ +
+ + +

Model component

+
+ +
+
+
+ + + +
diff --git a/Editor/resources/Interface/Testing.css b/Editor/resources/Interface/Testing.css index 3e40b00b..7095c2f5 100644 --- a/Editor/resources/Interface/Testing.css +++ b/Editor/resources/Interface/Testing.css @@ -7,6 +7,11 @@ width: 100%; } +.viewport { + height: 200px; + width: 200px; +} + .logo { width: 500px; height: 50%; diff --git a/Editor/resources/Interface/Testing.interface b/Editor/resources/Interface/Testing.interface index 6c4780ab..24c47bc7 100644 --- a/Editor/resources/Interface/Testing.interface +++ b/Editor/resources/Interface/Testing.interface @@ -6,10 +6,13 @@ width="100%" padding="8px 8px 8px 8px" > - +

Nuake Engine

You can load a project, or create a new one.

+ + + New Project

radius + if (length(coords - circle_center) >= radius && coords.x < circle_center.x && coords.y < circle_center.y) return true; //first circle circle_center.x += dimensions.x - 2 * radius; - if (length(coords - circle_center) > radius + if (length(coords - circle_center) >= radius && coords.x > circle_center.x && coords.y < circle_center.y) return true; //second circle circle_center.y += dimensions.y - 2 * radius; - if (length(coords - circle_center) > radius + if (length(coords - circle_center) >= radius && coords.x > circle_center.x && coords.y > circle_center.y) return true; //third circle circle_center.x -= dimensions.x - 2 * radius; - if (length(coords - circle_center) > radius + if (length(coords - circle_center) >= radius && coords.x < circle_center.x && coords.y > circle_center.y) return true; //fourth circle return false; @@ -59,5 +63,13 @@ void main() // Border rounding if (ShouldDiscard(coords, u_Size, u_BorderRadius)) discard; + FragColor = u_BackgroundColor; + + if (u_HasBackgroundTexture == 1) + { + vec2 uv = a_UV; + uv.y = 1.0 - a_UV.y; + FragColor = texture(u_BackgroundTexture, uv); + } } diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index ab37b164..1c0bd046 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -546,28 +546,6 @@ namespace Nuake { ImGui::Separator(); } } - - if (m_SelectedEntity.HasComponent()) { - - std::string icon = ICON_FA_TREE; - if (ImGui::CollapsingHeader((icon + " " + "Mesh").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Mesh properties"); - ImGui::Button("Drag Material"); - if (ImGui::BeginDragDropTarget()) - { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_DEMO_CELL")) - { - IM_ASSERT(payload->DataSize == sizeof(int)); - int payload_n = *(const int*)payload->Data; - - } - ImGui::EndDragDropTarget(); - } - } - - } - if (m_SelectedEntity.HasComponent()) { std::string icon = ICON_FA_BOWLING_BALL; @@ -579,7 +557,6 @@ namespace Nuake { ImGui::Separator(); } } - if (m_SelectedEntity.HasComponent()) { std::string icon = ICON_FA_BOX; @@ -981,10 +958,14 @@ namespace Nuake { unsigned int textureID = 0; if (m_SelectedMaterial->HasAlbedo()) textureID = m_SelectedMaterial->m_Albedo->GetID(); + if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image1"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { std::string texture = FileDialog::OpenFile("*.png | *.jpg"); + if (texture != "" && texture != m_SelectedMaterial->m_Albedo->GetPath()) + m_SelectedMaterial->m_Albedo = TextureManager::Get()->GetTexture(texture); } + ImGui::SameLine(); bool isAlbedo = m_SelectedMaterial->data.u_HasAlbedo == 1; ImGui::Checkbox("Use##1", &isAlbedo); diff --git a/Editor/src/FileSystemUI.cpp b/Editor/src/FileSystemUI.cpp index 1dcd14c4..b718adb3 100644 --- a/Editor/src/FileSystemUI.cpp +++ b/Editor/src/FileSystemUI.cpp @@ -130,7 +130,7 @@ namespace Nuake { dragType = "_Script"; else if (file->Type == ".map") dragType = "_Map"; - else if (file->Type == ".obj" || file->Type == ".mdl" || file->Type == ".gltf" || file->Type == ".md3" || file->Type == "fbx") + else if (file->Type == ".obj" || file->Type == ".mdl" || file->Type == ".gltf" || file->Type == ".md3" || file->Type == ".fbx") dragType = "_Model"; ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer)); diff --git a/Editor/src/NewEditor.cpp b/Editor/src/NewEditor.cpp new file mode 100644 index 00000000..756b0436 --- /dev/null +++ b/Editor/src/NewEditor.cpp @@ -0,0 +1,110 @@ +#include "NewEditor.h" +#include "Engine.h" +#include "src/Core/Input.h" +#include + +namespace Nuake +{ + NewEditor::NewEditor() + { + m_UserInterface = UI::UserInterface::New("Editor", "resources/Interface/Editor.interface"); + FetchNodes(); + } + + void NewEditor::FetchNodes() + { + m_SceneFramebuffer = Engine::GetCurrentWindow()->GetFrameBuffer(); + m_ViewportNode = m_UserInterface->GetNodeByID("viewport-texture"); + m_ViewportNode->BackgroundTexture = m_SceneFramebuffer->GetTexture(); + + m_FileMenu = m_UserInterface->GetNodeByID("action-menu-file"); + + m_Splitter = m_UserInterface->GetNodeByID("splitter"); + m_Splitter2 = m_UserInterface->GetNodeByID("splitter2"); + + m_Right = m_UserInterface->GetNodeByID("right"); + m_Left = m_UserInterface->GetNodeByID("left"); + m_Inspector = m_UserInterface->GetNodeByID("inspector"); + } + + bool dragging = false; + bool dragging2 = false; + void NewEditor::Update(Timestep ts) + { + if (Input::IsKeyPressed(GLFW_KEY_F1)) + { + m_UserInterface->Reload(); + FetchNodes(); + } + + if (m_FileMenu->IsClicked) + { + // Parse the project and load it. + std::string projectPath = FileDialog::OpenFile(".project"); + + FileSystem::SetRootDirectory(projectPath + "/../"); + Ref project = Project::New(); + if (!project->Deserialize(FileSystem::ReadFile(projectPath, true))) + { + Logger::Log("Error loading project: " + projectPath, CRITICAL); + return; + } + + project->FullPath = projectPath; + Engine::LoadProject(project); + } + float mouseX = Input::GetMouseX(); + if (m_Splitter->IsHover && Input::IsMouseButtonDown(0)) + { + dragging = true; + } + + if (m_Splitter2->IsHover && Input::IsMouseButtonDown(0)) + dragging2 = true; + + if (dragging) + { + if (!Input::IsMouseButtonDown(0)) + dragging = false; + + float totalWidth = m_UserInterface->Size.x; + + float mouseX = Input::GetMouseX(); + float ratio = mouseX / totalWidth; + + m_Inspector->NormalStyle.Width.Unit = Layout::PIXEL; + m_Inspector->NormalStyle.Width.Value = (1.0f - ratio) * totalWidth - 3.0f; + + m_ViewportNode->NormalStyle.Width.Unit = Layout::PIXEL; + m_ViewportNode->NormalStyle.Width.Value = ratio * totalWidth; + + m_Inspector->HoverStyle.Width.Unit = Layout::PIXEL; + m_Inspector->HoverStyle.Width.Value = (1.0f - ratio) * totalWidth - 3.0f; + + m_ViewportNode->HoverStyle.Width.Unit = Layout::PIXEL; + m_ViewportNode->HoverStyle.Width.Value = ratio * totalWidth; + + Logger::Log("mouseX " + std::to_string(ratio)); + } + + if (dragging2 == true) + { + if (!Input::IsMouseButtonDown(0)) + dragging2 = false; + + float totalWidth = m_UserInterface->Size.x; + float mouseX = Input::GetMouseX(); + float ratio = mouseX / totalWidth; + + } + + m_UserInterface->Update(ts); + + // Layout logic + } + + void NewEditor::Draw(Vector2 screenSize) + { + m_UserInterface->Draw(screenSize); + } +} \ No newline at end of file diff --git a/Editor/src/NewEditor.h b/Editor/src/NewEditor.h new file mode 100644 index 00000000..6d4a04f8 --- /dev/null +++ b/Editor/src/NewEditor.h @@ -0,0 +1,31 @@ +#pragma once +#include "src/Core/Core.h" +#include "src/UI/UserInterface.h" +#include "src/Core/Maths.h" +#include "src/Core/Timestep.h" +namespace Nuake +{ + class NewEditor + { + public: + NewEditor(); + + void Update(Timestep ts); + void Draw(Vector2 screenSize); + + private: + void FetchNodes(); + Ref m_UserInterface; + Ref m_SceneFramebuffer; + Ref m_ViewportNode; + + Ref m_FileMenu; + Ref m_Splitter; + Ref m_Splitter2; + Ref m_Left; + Ref m_Right; + Ref m_Inspector; + + bool fileOpened = false; + }; +} \ No newline at end of file diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index c5a75122..c88ba895 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -41,30 +41,30 @@ namespace Nuake void Engine::Tick() { - // Dont update if no scene is loaded. - if (!CurrentWindow->GetScene()) - return; - float time = (float)glfwGetTime(); Timestep timestep = time - m_LastFrameTime; m_LastFrameTime = time; - // Play mode update all the entities, Editor does not. - if (Engine::IsPlayMode) + // Dont update if no scene is loaded. + if (CurrentWindow->GetScene()) { - CurrentWindow->Update(timestep); - m_FixedUpdateDifference += timestep; - - // Fixed update - if (m_FixedUpdateDifference >= m_FixedUpdateRate) + // Play mode update all the entities, Editor does not. + if (Engine::IsPlayMode) { - CurrentWindow->FixedUpdate(m_FixedUpdateRate); - m_FixedUpdateDifference = 0.f; + CurrentWindow->Update(timestep); + m_FixedUpdateDifference += timestep; + + // Fixed update + if (m_FixedUpdateDifference >= m_FixedUpdateRate) + { + CurrentWindow->FixedUpdate(m_FixedUpdateRate); + m_FixedUpdateDifference = 0.f; + } + } + else + { + GetCurrentScene()->EditorUpdate(timestep); } - } - else - { - GetCurrentScene()->EditorUpdate(timestep); } Input::Update(); diff --git a/Nuake/PrefabComponent.h b/Nuake/PrefabComponent.h index b4c72efa..5ca32268 100644 --- a/Nuake/PrefabComponent.h +++ b/Nuake/PrefabComponent.h @@ -3,8 +3,12 @@ #include #include "src/Scene/Entities/Entity.h" -class PrefabComponent { -public: - Ref PrefabInstance; -}; \ No newline at end of file +namespace Nuake { + class PrefabComponent + { + public: + Ref PrefabInstance; + + }; +} diff --git a/Nuake/src/Core/Input.cpp b/Nuake/src/Core/Input.cpp index b51756a6..e34d4d80 100644 --- a/Nuake/src/Core/Input.cpp +++ b/Nuake/src/Core/Input.cpp @@ -64,17 +64,20 @@ namespace Nuake #pragma region Mouse // Visibility - void Input::HideMouse() { + void Input::HideMouse() + { auto window = Window::Get()->GetHandle(); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); } - bool Input::IsMouseHidden() { + bool Input::IsMouseHidden() + { auto window = Window::Get()->GetHandle(); return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; } - void Input::ShowMouse() { + void Input::ShowMouse() + { auto window = Window::Get()->GetHandle(); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } diff --git a/Nuake/src/Rendering/Textures/Texture.h b/Nuake/src/Rendering/Textures/Texture.h index c7bf1b44..2d7138a3 100644 --- a/Nuake/src/Rendering/Textures/Texture.h +++ b/Nuake/src/Rendering/Textures/Texture.h @@ -34,7 +34,7 @@ namespace Nuake void Unbind() const; unsigned int GetID() const { return m_RendererId; } - + inline std::string GetPath() { return m_FilePath; } inline int GetWidth() const { return m_Width; } inline int GetHeight() const { return m_Height; } }; diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index 2e5ffe52..69a4a620 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -3,20 +3,22 @@ #include #include -class Prefab -{ -public: - std::string Path; - std::vector Entities; - - Prefab() +namespace Nuake { + class Prefab { - Path = ""; - Entities = std::vector(); - } - - void AddEntity(Entity& entity) - { - Entities.push_back(entity); - } -}; \ No newline at end of file + public: + std::string Path; + std::vector Entities; + + Prefab() + { + Path = ""; + Entities = std::vector(); + } + + void AddEntity(Entity& entity) + { + Entities.push_back(entity); + } + }; +} diff --git a/Nuake/src/Scene/Components/LuaScriptComponent.h b/Nuake/src/Scene/Components/LuaScriptComponent.h index 9c926376..27820dab 100644 --- a/Nuake/src/Scene/Components/LuaScriptComponent.h +++ b/Nuake/src/Scene/Components/LuaScriptComponent.h @@ -6,4 +6,4 @@ class LuaScriptComponent public: std::string Script; -}; \ No newline at end of file +}; \ No newline at end of file diff --git a/Nuake/src/Scene/Components/MeshComponent.cpp b/Nuake/src/Scene/Components/MeshComponent.cpp index 997f7007..99d3d1ab 100644 --- a/Nuake/src/Scene/Components/MeshComponent.cpp +++ b/Nuake/src/Scene/Components/MeshComponent.cpp @@ -2,6 +2,7 @@ #include "src/Rendering/Textures/Material.h" #include "src/Rendering/Renderer.h" #include "src/Rendering/Textures/TextureManager.h" +#include namespace Nuake { void MeshComponent::Draw() @@ -15,7 +16,7 @@ namespace Nuake { this->meshes.clear(); Assimp::Importer import; import.SetPropertyFloat("PP_GSN_MAX_SMOOTHING_ANGLE", 90); - const aiScene* scene = import.ReadFile(FileSystem::Root + ModelPath, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace); + const aiScene* scene = import.ReadFile(FileSystem::Root + ModelPath, aiProcess_Triangulate |aiProcess_FixInfacingNormals | aiProcess_CalcTangentSpace); if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { @@ -92,21 +93,22 @@ namespace Nuake { for (unsigned int j = 0; j < face.mNumIndices; j++) indices.push_back(face.mIndices[j]); } + // process material if (mesh->mMaterialIndex >= 0) { aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; aiString str; - std::string directory = FileSystem::Root + this->ModelPath + "/../"; + std::string directory = FileSystem::Root + "/textures/d3b_concrt02a.png"; material->GetTexture(aiTextureType_DIFFUSE, 0, &str); - Ref newMaterial = CreateRef(TextureManager::Get()->GetTexture(directory + str.C_Str())); + Ref newMaterial = MaterialManager::Get()->GetMaterial(directory); //material->GetTexture(aiTextureType_NORMALS, 0, &str); //newMaterial->SetNormal(TextureManager::Get()->GetTexture(directory + str.C_Str())); - // + //material->GetTexture(aiTextureType_METALNESS, 0, &str); //newMaterial->SetMetalness(TextureManager::Get()->GetTexture(directory + str.C_Str())); - // + //material->GetTexture(aiTextureType_DIFFUSE_ROUGHNESS, 0, &str); //newMaterial->SetRoughness(TextureManager::Get()->GetTexture(directory + str.C_Str())); diff --git a/Nuake/src/Scene/Components/TransformComponent.h b/Nuake/src/Scene/Components/TransformComponent.h index ec74df03..5f49f6b5 100644 --- a/Nuake/src/Scene/Components/TransformComponent.h +++ b/Nuake/src/Scene/Components/TransformComponent.h @@ -8,7 +8,11 @@ namespace Nuake public: Vector3 GlobalTranslation; Vector3 Translation; + + Vector3 GlobalRotation; Vector3 Rotation; // TODO: Should use quaternions. + + Vector3 GlobalScale; Vector3 Scale; TransformComponent(); diff --git a/Nuake/src/Scene/EditorCamera.cpp b/Nuake/src/Scene/EditorCamera.cpp index 024df6d8..f7b0970a 100644 --- a/Nuake/src/Scene/EditorCamera.cpp +++ b/Nuake/src/Scene/EditorCamera.cpp @@ -33,11 +33,11 @@ namespace Nuake Speed = 0; // Keyboard - if (!controlled) { + if (!controlled) return; - } - if (m_Type == CAMERA_TYPE::ORTHO) { + if (m_Type == CAMERA_TYPE::ORTHO) + { if (Input::IsKeyDown(GLFW_KEY_RIGHT)) Translation.x += Speed * ts; if (Input::IsKeyDown(GLFW_KEY_LEFT)) @@ -47,7 +47,8 @@ namespace Nuake if (Input::IsKeyDown(GLFW_KEY_DOWN)) Translation.y -= Speed * ts; } - else { + else + { glm::vec3 movement = glm::vec3(0, 0, 0); if (Input::IsKeyDown(GLFW_KEY_D)) diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index efa83ac3..15a1a00b 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -177,6 +177,8 @@ namespace Nuake { Ref shadowShader = ShaderManager::GetShader("resources/Shaders/shadowMap.shader"); shadowShader->Bind(); + glCullFace(GL_BACK); + for (auto l : view) { auto [lightTransform, light] = view.get(l); @@ -268,6 +270,7 @@ namespace Nuake { pbrShader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z); pbrShader->SetUniform1i("u_ShowNormal", 0); + if (cam) { pbrShader->SetUniform1f("u_Exposure", cam->Exposure); @@ -281,7 +284,9 @@ namespace Nuake { for (auto& m : model.meshes) Renderer::SubmitMesh(m, transform.GetTransform()); } - + glCullFace(GL_BACK); + Renderer::Flush(pbrShader); + glCullFace(GL_FRONT); auto quakeView = m_Registry.view(); for (auto e : quakeView) { @@ -316,7 +321,6 @@ namespace Nuake { env->Push(); - glCullFace(GL_FRONT); glEnable(GL_DEPTH_TEST); // Register the lights @@ -346,6 +350,9 @@ namespace Nuake { for(auto& m : mesh.meshes) Renderer::SubmitMesh(m, transform.GetTransform()); } + glCullFace(GL_BACK); + Renderer::Flush(pbrShader); + glCullFace(GL_FRONT); auto quakeView = m_Registry.view(); for (auto e : quakeView) @@ -359,6 +366,7 @@ namespace Nuake { Renderer::SubmitMesh(b, transform.GetTransform()); } + glCullFace(GL_FRONT); Renderer::Flush(pbrShader); Ref flatShader = ShaderManager::GetShader("resources/Shaders/flat.shader"); @@ -407,7 +415,8 @@ namespace Nuake { } } - std::vector Scene::GetAllEntities() { + std::vector Scene::GetAllEntities() + { std::vector allEntities; auto view = m_Registry.view(); for (auto e : view) { diff --git a/Nuake/src/Scene/Systems/TransformSystem.cpp b/Nuake/src/Scene/Systems/TransformSystem.cpp index 5dcbb131..ff054cfe 100644 --- a/Nuake/src/Scene/Systems/TransformSystem.cpp +++ b/Nuake/src/Scene/Systems/TransformSystem.cpp @@ -1,7 +1,11 @@ #include "TransformSystem.h" + +#include "src/Core/Maths.h" + #include "src/Scene/Scene.h" #include "src/Scene/Components/TransformComponent.h" #include "src/Scene/Components/ParentComponent.h" +#include "src/Scene/Components/CameraComponent.h" namespace Nuake { TransformSystem::TransformSystem(Scene* scene) @@ -32,24 +36,44 @@ namespace Nuake { void TransformSystem::UpdateTransform() { + auto camView = m_Scene->m_Registry.view(); + for (auto e : camView) + { + auto [transform, camera] = camView.get(); + + Matrix4 cameraTransform = camera.CameraInstance->GetTransformRotation(); + + } + auto transformView = m_Scene->m_Registry.view(); - for (auto e : transformView) { + for (auto e : transformView) + { auto [parent, transform] = transformView.get(e); Entity currentParent = Entity((entt::entity)e, m_Scene); - Vector3 globalPos = Vector3(); + + Vector3 globalPosition = Vector3(); + Vector3 globalRotation = Vector3(); + Vector3 globalScale = Vector3(); if (parent.HasParent) { - while (currentParent.GetComponent().HasParent) + ParentComponent& parentComponent = currentParent.GetComponent(); + while (parentComponent.HasParent) { - currentParent = currentParent.GetComponent().Parent; - globalPos += currentParent.GetComponent().Translation; + TransformComponent& transformComponent = parentComponent.Parent.GetComponent(); + globalPosition += transformComponent.Translation; + globalRotation += transformComponent.Rotation; + globalScale *= transformComponent.Scale; } - - transform.GlobalTranslation = globalPos + transform.Translation; + + transform.GlobalTranslation = globalPosition + transform.Translation; + transform.GlobalRotation = globalRotation + transform.Rotation; + transform.GlobalScale = globalScale * transform.Scale; } else { transform.GlobalTranslation = transform.Translation; + transform.GlobalRotation = transform.Rotation; + transform.Scale = transform.Scale; } } } diff --git a/Nuake/src/UI/Font/FontLoader.h b/Nuake/src/UI/Font/FontLoader.h index cfb4033f..bf1a7738 100644 --- a/Nuake/src/UI/Font/FontLoader.h +++ b/Nuake/src/UI/Font/FontLoader.h @@ -104,7 +104,6 @@ namespace Nuake bool preprocess = false; int loaded = fontGeometry.loadCharset(font->GetFontHandle(), fontScale, charset, config.preprocessGeometry, config.kerning); - fonts.push_back(fontGeometry); if (glyphs.empty()) diff --git a/Nuake/src/UI/InterfaceParser.cpp b/Nuake/src/UI/InterfaceParser.cpp index 22e4bbb4..335b1fc4 100644 --- a/Nuake/src/UI/InterfaceParser.cpp +++ b/Nuake/src/UI/InterfaceParser.cpp @@ -65,6 +65,8 @@ namespace Nuake node->AddGroup(g); } } + if (name == "id") + node->ID = a.value(); if (name == "height") node->NormalStyle.Height = GetUnit(a.value()); if (name == "width") @@ -113,6 +115,8 @@ namespace Nuake node->AddGroup(g); } } + if (name == "id") + node->ID = a.value(); if (name == "height") node->NormalStyle.Height = GetUnit(a.value()); if (name == "width") @@ -267,6 +271,8 @@ namespace Nuake node->AddGroup(g); } } + if (name == "id") + node->ID = a.value(); if (name == "height") node->NormalStyle.Height = GetUnit(a.value()); if (name == "width") diff --git a/Nuake/src/UI/Nodes/Node.h b/Nuake/src/UI/Nodes/Node.h index 8f84c9eb..015a6f04 100644 --- a/Nuake/src/UI/Nodes/Node.h +++ b/Nuake/src/UI/Nodes/Node.h @@ -17,9 +17,13 @@ namespace Nuake class Node { public: + float ScrollAmount = 0.0f; + int Depth; Ref Root; Ref Parent; + std::string ID; + std::vector Groups; std::vector> Childrens = std::vector>(); @@ -30,9 +34,13 @@ namespace Nuake YGNodeRef YogaNode; bool IsHover = false; + bool IsClicked = false; + Style NormalStyle; Style HoverStyle; + Ref BackgroundTexture; + Node(); void ApplyStyle(Ref stylegroup, StyleGroupSelector selector = StyleGroupSelector::Normal); @@ -44,10 +52,16 @@ namespace Nuake Groups.push_back(group); } + float GetWidth() + { + return YGNodeLayoutGetWidth(YogaNode); + } + bool IsInGroup(const std::string& group) { for (auto& g : Groups) if (g == group) return true; + return false; } @@ -302,20 +316,32 @@ namespace Nuake color.r / 255.f, color.g / 255.f, color.b / 255.f, - color.a / 255.f); + color.a / 255.f + ); - // Get transform Matrix4 transform = Matrix4(1.0f); float width = YGNodeLayoutGetWidth(YogaNode); float height = YGNodeLayoutGetHeight(YogaNode); + + float scrollRange = height; + + float padding = YGNodeLayoutGetPadding(YogaNode, YGEdgeLeft); float left = YGNodeLayoutGetLeft(YogaNode); //+ offset.x; float top = YGNodeLayoutGetTop(YogaNode);// +offset.y; float parentLeft = 0.0f; float parentTop = 0.0f; + float parentHeight = 0.0f; + float parentWidth = 0.0f; + auto parent = YGNodeGetParent(YogaNode); + if (parent) + { + parentHeight = YGNodeLayoutGetHeight(parent); + parentWidth = YGNodeLayoutGetWidth(parent); + } while (parent) { @@ -323,33 +349,32 @@ namespace Nuake parentTop += YGNodeLayoutGetTop(parent); parent = YGNodeGetParent(parent); } - if (parent) - { - //parentLeft = YGNodeLayoutGetLeft(YGNodeGetParent(YogaNode)); - //parentTop = YGNodeLayoutGetTop(YGNodeGetParent(YogaNode)); - //float parentPaddingTop = YGNodeLayoutGetPadding(parent, YGEdgeTop); - //float parentPaddingLeft = YGNodeLayoutGetPadding(parent, YGEdgeTop); - // Overflow hidden. - //float parentwidth = YGNodeLayoutGetWidth(parent); - //if (parentwidth - YGNodeLayoutGetMargin(YogaNode, YGEdgeLeft) < width) - // width = parentwidth - parentPaddingLeft; - //float parentHeight = YGNodeLayoutGetHeight(parent); - //if (parentHeight < height) - // height = parentHeight - YGNodeLayoutGetMargin(YogaNode, YGEdgeTop) - parentPaddingTop; - } transform = glm::translate(transform, Vector3(left + parentLeft, top + parentTop, 0.f)); + //if (top + height > parentHeight) + //{ + // float heightDifference = parentHeight - (top + height); + // height = height + heightDifference; + //} Vector3 scale = Vector3(width, height, 0); transform = glm::scale(transform, scale); - - //Logger::Log("Left: " + std::to_string(left) + " Top:" + std::to_string(top)); + Renderer2D::UIShader->SetUniformMat4f("model", transform); Renderer2D::UIShader->SetUniform1f("u_BorderRadius", NormalStyle.Border.Left.Value); Renderer2D::UIShader->SetUniform2f("u_Size", width, height); + if (BackgroundTexture != nullptr) + { + BackgroundTexture->Bind(1); + Renderer2D::UIShader->SetUniform1i("u_BackgroundTexture", 1); + Renderer2D::UIShader->SetUniform1i("u_HasBackgroundTexture", 1); + } + else + Renderer2D::UIShader->SetUniform1i("u_HasBackgroundTexture", 0); + Renderer2D::DrawRect(); } }; -} +} \ No newline at end of file diff --git a/Nuake/src/UI/UserInterface.cpp b/Nuake/src/UI/UserInterface.cpp index 83c89706..3d95a643 100644 --- a/Nuake/src/UI/UserInterface.cpp +++ b/Nuake/src/UI/UserInterface.cpp @@ -12,6 +12,7 @@ namespace Nuake { UserInterface::UserInterface(const std::string& name, const std::string& path) { m_Name = name; + m_Path = path; font = FontLoader::LoadFont("resources/Fonts/OpenSans-Regular.ttf"); Root = InterfaceParser::Parse(path); @@ -36,7 +37,7 @@ namespace Nuake { void UserInterface::Reload() { - Root = InterfaceParser::Parse("resources/Interface/Testing.interface"); + Root = InterfaceParser::Parse(this->m_Path); if (!Root) { Logger::Log("Failed to generate interface structure", CRITICAL); @@ -111,6 +112,7 @@ namespace Nuake { Calculate(size.x, size.y); Renderer2D::BeginDraw(size); DrawRecursive(Root, 0); + Size = size; } void UserInterface::DrawRecursive(Ref node, float z) @@ -134,14 +136,11 @@ namespace Nuake { void UserInterface::Update(Timestep ts) { - // Check Input - if (Input::IsMouseButtonPressed(0)) - { - ConsumeMouseClick(Input::GetMousePosition()); - } - // Hover RecursiveHover(Root, Input::GetMousePosition()); + + // Check Input + ConsumeMouseClick(Input::GetMousePosition()); } void UserInterface::RecursiveHover(Ref node, Vector2 pos) @@ -152,6 +151,7 @@ namespace Nuake { bool isHover = c->IsPositionInside(pos); c->IsHover = isHover; + c->IsClicked = false; if (isHover) { for (auto& g : c->GetGroups()) @@ -169,17 +169,46 @@ namespace Nuake { void UserInterface::RecursiveMouseClick(Ref node, Vector2 pos) { + if (node->IsHover) + { + node->IsClicked = true; + } + for (auto& c : node->Childrens) { RecursiveMouseClick(c, pos); - if (c->IsPositionInside(pos) && c->OnClickSignature != "") - this->Root->Script->CallMethod(c->OnClickSignature); } } void UserInterface::ConsumeMouseClick(Vector2 pos) { - RecursiveMouseClick(Root, pos); + if(Input::IsMouseButtonPressed(0)) + RecursiveMouseClick(Root, pos); + } + + + Ref UserInterface::GetNodeByID(const std::string& id) + { + for (auto& n : Root->Childrens) + { + Ref result = GetNodeByIDRecurse(n, id); + if (result) + return result; + } + } + + Ref UserInterface::GetNodeByIDRecurse(Ref node, const std::string& id) + { + for (auto& n : node->Childrens) + { + if (n->ID == id) + return n; + + Ref result = GetNodeByIDRecurse(n, id); + if (result != nullptr) + return result; + } + return nullptr; } } } diff --git a/Nuake/src/UI/UserInterface.h b/Nuake/src/UI/UserInterface.h index 1a6112b9..1994fbb4 100644 --- a/Nuake/src/UI/UserInterface.h +++ b/Nuake/src/UI/UserInterface.h @@ -23,13 +23,16 @@ namespace Nuake { YGConfigRef yoga_config; YGNodeRef yoga_root; - + + Ref GetNodeByIDRecurse(Ref node, const std::string& id); void RecursiveHover(Ref node, Vector2 pos); public: Ref font; const int Width = 1920; const int Height = 1080; + Vector2 Size = Vector2(); + UserInterface(const std::string& name, const std::string& path); ~UserInterface(); @@ -47,6 +50,8 @@ namespace Nuake { void RecursiveStyle(Ref node); void RecursiveMouseClick(Ref node, Vector2 pos); + Ref GetNodeByID(const std::string& id); + void ConsumeMouseClick(Vector2 pos); }; }