diff --git a/imgui.ini b/imgui.ini index 33f0cea..06aa31c 100644 --- a/imgui.ini +++ b/imgui.ini @@ -131,7 +131,7 @@ DockId=0x00000010,0 [Window][Import Preview] Pos=351,22 -Size=550,695 +Size=550,1152 Collapsed=0 [Table][0x96376740,2] diff --git a/remake/build.log b/remake/build.log index 9d26f09..28a00f3 100644 --- a/remake/build.log +++ b/remake/build.log @@ -1,4 +1,3 @@ -[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\editor\windows\AssetBrowser.cpp -o src\build\editor\windows\AssetBrowser.o -[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\AudioPlayerComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\audio\AudioEngine.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Popup.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\AudioInfo.o src\build\editor\windows\Inspector.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o src\build\miniaudio.o src\build\ImGuizmo.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -ldbghelp -[ERROR] Runtime crash -Command 'src\build\app.exe' returned non-zero exit status 3. +[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Engine.cpp -o src\build\Engine.o +[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\AudioPlayerComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\audio\AudioEngine.o src\build\core\functions\Prefab.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Popup.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\AudioInfo.o src\build\editor\windows\Inspector.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o src\build\miniaudio.o src\build\ImGuizmo.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -ldbghelp +[RUN] Executed app.exe successfully. diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp index bc31c1e..4c6887f 100644 --- a/src/src/Engine.cpp +++ b/src/src/Engine.cpp @@ -17,6 +17,9 @@ #include "core/audio/AudioEngine.h" #include "core/utils/EngineConfig.h" + +#include "core/functions/Prefab.h" + #include "utils/GameObjectsList.h" #include "core/utils/Profiler.h" #include "core/utils/utils.h" @@ -36,8 +39,6 @@ #include - - #include #include #include @@ -58,8 +59,6 @@ #include using json = nlohmann::json; - - static std::shared_ptr selected = nullptr; static bool playing = false; static bool lastPlaying = false; @@ -80,7 +79,6 @@ static const std::string tempScenePath = "__tmp_scene.yaml"; GLFWwindow *window = nullptr; - Engine::Engine() { @@ -765,6 +763,7 @@ void Engine::Run() if (ImGui::BeginMenu("Defaults")) { ImGui::Checkbox("Prompt Outdated Scenes", &g_engineConfig.settings.ignore_invalid_versions_popups); + ImGui::EndMenu(); } if (ImGui::BeginMenu("Profiling")) { @@ -1254,7 +1253,6 @@ void Engine::Run() { previewObj = nullptr; previewUAID = 0; - } else if (previewObj && (!hoveringViewport || !draggingTexture)) { @@ -1360,6 +1358,7 @@ void Engine::DrawObjectNode(const std::shared_ptr &obj) selected = child; ImGui::OpenPopup("RenameObject"); } + if (ImGui::MenuItem("Duplicate")) { auto clone = std::make_shared(*obj); @@ -1377,6 +1376,19 @@ void Engine::DrawObjectNode(const std::shared_ptr &obj) ImGui::OpenPopup("RenameObject"); } + if (ImGui::MenuItem("Convert to Prefab")) + { + std::string path = Prefab::CreatePrefab(obj, "C:/Users/spenc/OneDrive/Desktop"); + if (!path.empty()) + { + Logger::LogInfo("[Prefab] Saved prefab to: %s", path.c_str()); + } + else + { + Logger::LogError("[Prefab] Failed to create prefab."); + } + } + ImGui::EndPopup(); } @@ -1522,7 +1534,7 @@ void Engine::LoadScene(const std::string &path) if (loadedVersion != expectedVersion) { Logger::LogWarning("[LoadScene] Version mismatch! Expected %s, got %s", - expectedVersion.c_str(), loadedVersion.c_str()); + expectedVersion.c_str(), loadedVersion.c_str()); if (!g_engineConfig.settings.ignore_invalid_versions_popups) { diff --git a/src/src/core/functions/Prefab.cpp b/src/src/core/functions/Prefab.cpp new file mode 100644 index 0000000..6ba932f --- /dev/null +++ b/src/src/core/functions/Prefab.cpp @@ -0,0 +1,70 @@ +#include "Prefab.h" +#include "../utils/Logging.h" +#include "../utils/utils.h" +#include "../../Entitys/Object.h" +#include "../../core/utils/AssetManager.h" + +#include +#include +#include +#include +#include +#include + +std::string Prefab::CreatePrefab(const std::shared_ptr& obj, const std::string& outputDir) +{ + if (!obj) + { + Logger::LogError("[Prefab] Cannot create prefab from null object."); + return ""; + } + + std::string name = obj->GetName().empty() ? "Unnamed" : obj->GetName(); + for (char& c : name) + { + if (!std::isalnum(c) && c != '_' && c != '-' && c != ' ') + c = '_'; + } + + // Emit object YAML + YAML::Emitter objectOut; + objectOut.SetIndent(2); + obj->Save(objectOut); + + // Wrap metadata + YAML::Emitter out; + out.SetIndent(2); + + std::string hash = HashString(objectOut.c_str()); + std::time_t now = std::time(nullptr); + + out << YAML::BeginMap; + out << YAML::Key << "uaid" << YAML::Value << AssetManager::GenerateUAID(); + out << YAML::Key << "filename" << YAML::Value << name + ".cpfb"; + out << YAML::Key << "filetype" << YAML::Value << "cpfb"; + out << YAML::Key << "type" << YAML::Value << "Prefab"; + out << YAML::Key << "prefabName" << YAML::Value << name; + out << YAML::Key << "hash" << YAML::Value << hash; + out << YAML::Key << "lastModified" << YAML::Value << now; + out << YAML::Key << "loaded" << YAML::Value << true; + out << YAML::Key << "prefabYAML" << YAML::Value << objectOut.c_str(); + out << YAML::EndMap; + + // Output file + std::filesystem::create_directories(outputDir); + std::string fullPath = outputDir + "/" + name + ".cpfb"; + + std::ofstream file(fullPath); + if (file.is_open()) + { + file << out.c_str(); + file.close(); + Logger::LogInfo("[Prefab] Saved prefab: %s", fullPath.c_str()); + return fullPath; + } + else + { + Logger::LogError("[Prefab] Failed to save prefab: %s (%s)", fullPath.c_str(), std::strerror(errno)); + return ""; + } +} diff --git a/src/src/core/functions/Prefab.h b/src/src/core/functions/Prefab.h new file mode 100644 index 0000000..bb48884 --- /dev/null +++ b/src/src/core/functions/Prefab.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +class Object; + +namespace Prefab +{ + // Saves the object as a .cpfb prefab file + // Returns the full path it saved to (empty string on failure) + std::string CreatePrefab(const std::shared_ptr& obj, const std::string& outputDir); +} diff --git a/src/src/core/utils/AssetManager.h b/src/src/core/utils/AssetManager.h index 9c8c2d5..c121534 100644 --- a/src/src/core/utils/AssetManager.h +++ b/src/src/core/utils/AssetManager.h @@ -94,12 +94,14 @@ public: static void Save(YAML::Emitter& out); static void Load(const YAML::Node& node); + static uint64_t GenerateUAID(); + + private: static std::unordered_map> s_Assets; static std::unordered_map s_PathToUAID; static uint64_t s_NextUAID; - static uint64_t GenerateUAID(); static void LoadImageInternal(const std::string& path, uint64_t uaid); static void LoadAudioInternal(const std::string& path, uint64_t uaid); static void LoadPrefabInternal(const std::string& path, uint64_t uaid);