#pragma once #include #include #include #include #include #include "Inspector.h" #include "Console.h" #include "IconsMaterialDesign.h" #include "Project.h" #include "EditorCamera.h" using namespace YoggieEngine; class EditorLayer : public Layer { public: EditorLayer() : Layer() { Logo.Load("rsc/Yoggie.png"); Selected = YoggieEngine::Entity{ (entt::entity)-1, (scene.get()) }; } void OnStartup() override { std::string path = (std::filesystem::current_path()).string(); scene = std::make_unique(); project = std::make_unique(); project.get()->setProjectDirectory(path); LoadLastOrEmptyProject(); //Console console = Console(); } void OnUpdate() override { scene.get()->Update(); renderer.get()->Render(*scene, *camera); } void OnUI() override { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { ImGui::GetWindowWidth(), 7 }); ImGui::BeginMainMenuBar(); int scaleFactor = 30; ImGui::Image((ImTextureID)Logo.GetID(), { Logo.getSize().x / scaleFactor , Logo.getSize().y / scaleFactor }); ImGui::PopStyleVar(); if (ImGui::BeginMenu("App")) { if (ImGui::MenuItem("Load Project")) { nfdresult_t result = NFD_OpenDialog({ "yproj" }, NULL, &path); switch (result) { case(NFD_OKAY): //Project::LoadProject(path, project); //AssetRegistry::setAssetPath(project.GetProjectDirectory()); //AssetRegistry::BuildAssetView(); break; case(NFD_CANCEL): break; case(NFD_ERROR): spdlog::error("NFD_Error: {0}", NFD_GetError()); break; } } if (ImGui::MenuItem("Save project as...")) { nfdresult_t result = NFD_SaveDialog({ "yproj" }, NULL, &path); switch (result) { case(NFD_OKAY): spdlog::info("Save as: {0}", path); //Project::SaveProject(path, project); break; case(NFD_CANCEL): break; case(NFD_ERROR): spdlog::error("NFD_Error: {0}", NFD_GetError()); break; } } ImGui::EndMenu(); } if (ImGui::BeginMenu("Scene")) { if (ImGui::MenuItem("Save scene")) { nfdresult_t result = NFD_SaveDialog({ "yscene" }, NULL, &path); switch (result) { case(NFD_OKAY): //SaveScene(path, scene); //project.AddScene(scene); break; case(NFD_CANCEL): break; case(NFD_ERROR): std::cout << "NFD_Error: " << NFD_GetError() << std::endl; break; } } if (ImGui::MenuItem("Load scene")) { auto result = NFD_OpenDialog({ "yscene" }, NULL, &path); switch (result) { case (NFD_OKAY): //LoadScene(path, scene); break; case(NFD_CANCEL): break; case(NFD_ERROR): std::cout << "NFD_Error: " << NFD_GetError() << std::endl; break; } } if (ImGui::MenuItem("Add Entity")) { //scene.AddEntity("New Entity"); } if (ImGui::MenuItem("Import Model")) { auto result = NFD_OpenDialog("obj,fbx,gltf", NULL, &path); switch (result) { case(NFD_OKAY): // Import Model /* AssetRegistry::LoadFromSource( path, "build/Debug/Assets"//project.get()->GetProjectDirectory() / "Assets" ); */ break; case(NFD_CANCEL): break; case(NFD_ERROR): std::cout << "NFD_Error: " << NFD_GetError() << std::endl; break; } } if (ImGui::MenuItem("Import MeshAsset (temp)")) { auto result = NFD_OpenDialog("mesh", NULL, &path); switch (result) { case(NFD_OKAY): { } break; case(NFD_CANCEL): spdlog::debug("User cancelled action"); break; case(NFD_ERROR): spdlog::warn("Something went wrong!"); break; } } ImGui::EndMenu(); } ImGui::SameLine(ImGui::GetWindowWidth() / 4 * 3); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.3f, 0.3f, 0.3f, 1.0f)); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); ImGui::Button(ICON_MD_ROCKET_LAUNCH "Project"); ImGui::SameLine(ImGui::GetWindowWidth() - 120); ImGui::PopStyleColor(1); ImGui::PopStyleVar(); ImGui::EndMainMenuBar(); ImGui::Begin("RuntimeControls"); ImGui::BeginGroup(); ImGui::SameLine(); ImGui::Text(ICON_MD_TRANSFORM); auto spacing = 10; float buttonWidth = 75.0f; float buttonHeight = 30; float ColorIntensity = 0.5f; float ColorIntensityHovered = 0.75; float ColorIntensityActive = 0.85; float yPadding = 6.f; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{0, yPadding }); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{ 0.0f,ColorIntensity ,0.0f ,1.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4{ 0.0f,ColorIntensityHovered ,0.0f ,1.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{ 0.0f,ColorIntensityActive ,0.0f ,1.0f }); ImGui::SameLine(0, spacing); if (ImGui::Button("Translate", { buttonWidth,buttonHeight })) activeOperation = ImGuizmo::OPERATION::TRANSLATE; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{ 0, yPadding }); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{ ColorIntensity, 0.0f ,0.0f ,1.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4{ ColorIntensityHovered, 0.0f ,0.0f ,1.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{ ColorIntensityActive, 0.0f ,0.0f ,1.0f }); ImGui::SameLine(0, spacing); if (ImGui::Button("Rotate", { buttonWidth,buttonHeight })) activeOperation = ImGuizmo::OPERATION::ROTATE; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{ 0, yPadding }); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{ 0.0f, 0.0f ,ColorIntensity ,1.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4{ 0.0f, 0.0f ,ColorIntensityHovered ,1.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{ 0.0f, 0.0f ,ColorIntensityActive ,1.0f }); ImGui::SameLine(0, spacing); if (ImGui::Button("Scale", { buttonWidth,buttonHeight })) activeOperation = ImGuizmo::OPERATION::SCALE; ImGui::PopStyleColor(9); ImGui::PopStyleVar(3); ImGui::EndGroup(); ImGui::SameLine((ImGui::GetWindowContentRegionMax().x / 2) - (90)); auto color = ImVec4{ 0.001 * 12 , 0.001 * 201 , 0.001 * 69, 1.0f }; ImGui::PushStyleColor(ImGuiCol_Button, color); const float strengthIncrease = 1.5f; ImGui::PushStyleColor( ImGuiCol_ButtonHovered, ImVec4{ color.x * strengthIncrease, color.y * strengthIncrease, color.z * strengthIncrease, color.w } ); if (ImGui::Button(ICON_MD_PLAY_ARROW, { 90,25 })) { // Play game } ImGui::PopStyleColor(2); ImGui::SameLine(); color = ImVec4{ 0.001 * 14, 0.001 * 157, 0.001 * 201, 1.0f }; ImGui::PushStyleColor(ImGuiCol_Button, color); ImGui::PushStyleColor( ImGuiCol_ButtonHovered, ImVec4{ color.x * strengthIncrease, color.y * strengthIncrease, color.z * strengthIncrease, color.w } ); if (ImGui::Button(ICON_MD_ELECTRIC_BOLT, { 90,25 })) { // Simulate physics } ImGui::PopStyleColor(2); ImGui::End(); unsigned int viewportWindowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse; ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0,0 }); ImGui::Begin("SceneView",nullptr,viewportWindowFlags); // spdlog::info("{0}x{1}", ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); SceneisFocused = ImGui::IsWindowFocused() || ImGui::IsWindowHovered(); ImGui::Image((ImTextureID)(intptr_t)renderer.get()->getCurrentFrameBuffer().GetColourAttachment(), ImVec2{(float)ImGui::GetWindowWidth(),(float)ImGui::GetWindowHeight()}); //ImGuizmo::ViewManipulate(glm::value_ptr(cameraView), 1, ImGui::GetWindowPos(), { 90,90 }, 0x22CCCCCCC); if(Selected.isValid()){ ImGuizmo::SetOrthographic(false); ImGuizmo::SetDrawlist(); ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); const auto& ProjMatrix = camera->getProjection(ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); const glm::mat4& viewMatrix = glm::inverse(camera->getTransform()); auto& tc = Selected.GetComponent(); auto transform = tc.GetTransform(); ImGuizmo::Manipulate( glm::value_ptr(viewMatrix), glm::value_ptr(ProjMatrix), activeOperation, ImGuizmo::LOCAL, glm::value_ptr(transform)); if (ImGuizmo::IsUsing()) { tc.Decompose(transform); } } ImGui::End(); ImGui::PopStyleVar(); ImGui::Begin("EditorCamera"); ImGui::SliderFloat3("position", glm::value_ptr(camera->Position), -50, 50); ImGui::End(); ImGui::Begin(ICON_MD_MENU "SceneExplorer",nullptr); scene.get()->getReg().each([&](entt::entity enttNumber) { YoggieEngine::Entity entity = YoggieEngine::Entity(enttNumber, &*scene.get()); auto id = entity.GetComponent(); if (ImGui::Selectable(id.name.c_str(), entity == Selected)) { Selected = YoggieEngine::Entity(enttNumber, &*scene); } }); ImGui::End(); { ImGui::Begin("Asset", nullptr); const char* hidden_extensions[]{ ".exe", ".pdb", ".idb", ".dll", ".ini" }; std::vector files = std::vector(); int iconSize = 60; int maxColumns = 3; YoggieEngine::Texture folderIcon; YoggieEngine::Texture assetIcon; //assetIcon = YoggieEngine::Texture("rsc/AssetIcon.png"); ImGui::DragInt("IconSize", &iconSize, 1, 30, 90); ImGui::DragInt("Max. Columns", &maxColumns, 1, 1, 6); if (ImGui::BeginTable("##Resources", 3)) { ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 1.f, 1.f, 0.2f)); int row = 0; int column = 0; for (auto& asset : files) { if (column % 3 == 0) { ImGui::TableNextRow(); column = 0; row++; } ImGui::TableSetColumnIndex(column); ImGui::ImageButton( (ImTextureID)assetIcon.GetID(), ImVec2{ (float)iconSize, (float)iconSize }); ImGui::Text(asset.Handle.String().c_str(), row); column++; } ImGui::PopStyleColor(3); ImGui::EndTable(); } ImGui::End(); } ImGui::ShowDemoWindow(); //ImGui::ShowMetricsWindow(); } void OnCreate() override { spdlog::info(" Layer Create!" ); } void OnDestroy() override { spdlog::info( " Layer Destroy!" ); } bool OnKey(int key, int mode) override { float movement_speed = 0.10f; if (SceneisFocused) { if (key == YOGGIE_KEY_UP) camera->Rotation.x += movement_speed; if (key == YOGGIE_KEY_DOWN) camera->Rotation.x -= movement_speed; if (key == YOGGIE_KEY_LEFT) camera->Rotation.y += movement_speed; if (key == YOGGIE_KEY_RIGHT) camera->Rotation.y -= movement_speed; if (key == YOGGIE_KEY_A) camera->Position += glm::vec3(1.0f, 0.0f, 0.0f) * movement_speed; if (key == YOGGIE_KEY_S) camera->Position += glm::vec3(0.0f, 0.0f, -1.0f) * movement_speed; if (key == YOGGIE_KEY_D) camera->Position -= glm::vec3(1.0f, 0.0f, 0.0f) * movement_speed; if (key == GLFW_KEY_W) camera->Position -= glm::vec3(0.0f, 0.0f, -1.0f) * movement_speed; } return true; } private: std::unique_ptr inspector = std::make_unique(Selected); std::unique_ptr renderer = std::make_unique(); std::unique_ptr camera = std::make_unique(); std::unique_ptr project; std::unique_ptr scene; Texture Logo; bool SimulatePhysics = true; bool SceneisFocused = false; YoggieEngine::Entity Selected; ImGuizmo::OPERATION activeOperation = ImGuizmo::OPERATION::TRANSLATE; char* path = nullptr; void LoadLastOrEmptyProject() { // Check if there is a last known loaded project and // load that one . // Otherwise load no project.. // OR // Load an empty project. mINI::INIStructure ini; if (std::filesystem::exists("build\\Debug\\Editor.ini")) { mINI::INIFile file("build\\Debug\\Editor.ini"); file.read(ini); } else { spdlog::debug("Could not find an `Editor.ini` file."); } if (ini["editor"]["openlastproject"] == "TRUE") { Project::LoadProject(ini["cache"]["project"], *project); ///LoadScene(ini["cache"]["scene"], scene); } else { spdlog::debug("Starting without a project. Please create one."); } } };