From 7b71e8823ff6d6e7d1c5bcd5c455ff9ddac1ea43 Mon Sep 17 00:00:00 2001 From: Pier-Olivier Boulianne Date: Sun, 11 May 2025 00:08:11 -0400 Subject: [PATCH 1/9] Initial Asset Manager work --- StarEditor/src/EditorLayer.cpp | 10 +++ StarEditor/src/EditorLayer.h | 1 + .../src/Platform/OpenGL/OpenGLTexture.cpp | 61 ++----------------- .../src/Platform/OpenGL/OpenGLTexture.h | 8 +-- .../src/Platform/Windows/WindowsWindow.cpp | 12 ++++ StarEngine/src/StarEngine/Asset/Asset.cpp | 6 ++ StarEngine/src/StarEngine/Asset/Asset.h | 23 +++++++ .../src/StarEngine/Asset/AssetImporter.cpp | 25 ++++++++ .../src/StarEngine/Asset/AssetImporter.h | 13 ++++ .../src/StarEngine/Asset/AssetManager.cpp | 7 +++ .../src/StarEngine/Asset/AssetManager.h | 19 ++++++ .../src/StarEngine/Asset/AssetManagerBase.cpp | 7 +++ .../src/StarEngine/Asset/AssetManagerBase.h | 19 ++++++ .../src/StarEngine/Asset/AssetMetadata.h | 16 +++++ .../StarEngine/Asset/EditorAssetManager.cpp | 55 +++++++++++++++++ .../src/StarEngine/Asset/EditorAssetManager.h | 27 ++++++++ .../StarEngine/Asset/RuntimeAssetManager.cpp | 7 +++ .../StarEngine/Asset/RuntimeAssetManager.h | 11 ++++ .../src/StarEngine/Asset/TextureImporter.cpp | 50 +++++++++++++++ .../src/StarEngine/Asset/TextureImporter.h | 15 +++++ StarEngine/src/StarEngine/Core/Buffer.h | 9 ++- .../src/StarEngine/Events/ApplicationEvent.h | 21 ++++++- StarEngine/src/StarEngine/Events/Event.h | 2 +- StarEngine/src/StarEngine/Project/Project.h | 7 +++ StarEngine/src/StarEngine/Renderer/Font.cpp | 2 +- .../src/StarEngine/Renderer/Renderer2D.cpp | 2 +- .../src/StarEngine/Renderer/Texture.cpp | 16 +---- StarEngine/src/StarEngine/Renderer/Texture.h | 17 +++--- StarEngine/src/sepch.h | 4 +- 29 files changed, 383 insertions(+), 89 deletions(-) create mode 100644 StarEngine/src/StarEngine/Asset/Asset.cpp create mode 100644 StarEngine/src/StarEngine/Asset/Asset.h create mode 100644 StarEngine/src/StarEngine/Asset/AssetImporter.cpp create mode 100644 StarEngine/src/StarEngine/Asset/AssetImporter.h create mode 100644 StarEngine/src/StarEngine/Asset/AssetManager.cpp create mode 100644 StarEngine/src/StarEngine/Asset/AssetManager.h create mode 100644 StarEngine/src/StarEngine/Asset/AssetManagerBase.cpp create mode 100644 StarEngine/src/StarEngine/Asset/AssetManagerBase.h create mode 100644 StarEngine/src/StarEngine/Asset/AssetMetadata.h create mode 100644 StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp create mode 100644 StarEngine/src/StarEngine/Asset/EditorAssetManager.h create mode 100644 StarEngine/src/StarEngine/Asset/RuntimeAssetManager.cpp create mode 100644 StarEngine/src/StarEngine/Asset/RuntimeAssetManager.h create mode 100644 StarEngine/src/StarEngine/Asset/TextureImporter.cpp create mode 100644 StarEngine/src/StarEngine/Asset/TextureImporter.h diff --git a/StarEditor/src/EditorLayer.cpp b/StarEditor/src/EditorLayer.cpp index beb2abb..a8896d0 100644 --- a/StarEditor/src/EditorLayer.cpp +++ b/StarEditor/src/EditorLayer.cpp @@ -464,6 +464,7 @@ namespace StarEngine { EventDispatcher dispatcher(e); dispatcher.Dispatch(SE_BIND_EVENT_FN(EditorLayer::OnKeyPressed)); dispatcher.Dispatch(SE_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressed)); + dispatcher.Dispatch(SE_BIND_EVENT_FN(EditorLayer::OnWindowDrop)); } bool EditorLayer::OnKeyPressed(KeyPressedEvent& e) @@ -578,6 +579,15 @@ namespace StarEngine { return false; } + bool EditorLayer::OnWindowDrop(WindowDropEvent& e) + { + // TODO: if a project is dropped in, probably open it + + //AssetManager::ImportAsset(); + + return true; + } + void EditorLayer::OnOverlayRender() { if (m_SceneState == SceneState::Play) diff --git a/StarEditor/src/EditorLayer.h b/StarEditor/src/EditorLayer.h index 31b60c1..149c471 100644 --- a/StarEditor/src/EditorLayer.h +++ b/StarEditor/src/EditorLayer.h @@ -27,6 +27,7 @@ namespace StarEngine private: bool OnKeyPressed(KeyPressedEvent& e); bool OnMouseButtonPressed(MouseButtonPressedEvent& e); + bool OnWindowDrop(WindowDropEvent& e); void OnOverlayRender(); diff --git a/StarEngine/src/Platform/OpenGL/OpenGLTexture.cpp b/StarEngine/src/Platform/OpenGL/OpenGLTexture.cpp index bfa8d6f..8f1801f 100644 --- a/StarEngine/src/Platform/OpenGL/OpenGLTexture.cpp +++ b/StarEngine/src/Platform/OpenGL/OpenGLTexture.cpp @@ -1,7 +1,7 @@ #include "sepch.h" #include "Platform/OpenGL/OpenGLTexture.h" -#include +#include "stb_image.h" namespace StarEngine { @@ -33,7 +33,7 @@ namespace StarEngine { } - OpenGLTexture2D::OpenGLTexture2D(const TextureSpecification& specification) + OpenGLTexture2D::OpenGLTexture2D(const TextureSpecification& specification, Buffer data) : m_Specification(specification), m_Width(m_Specification.Width), m_Height(m_Specification.Height) { SE_PROFILE_FUNCTION(); @@ -49,58 +49,9 @@ namespace StarEngine { glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT); glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - - OpenGLTexture2D::OpenGLTexture2D(const std::string& path) - : m_Path(path) - { - SE_PROFILE_FUNCTION(); - - int width, height, channels; - stbi_set_flip_vertically_on_load(1); - stbi_uc* data = nullptr; - { - SE_PROFILE_FUNCTION("stbi_load - OpenGLTexture2D::OpenGLTexture2D(const std::string&)"); - data = stbi_load(path.c_str(), &width, &height, &channels, 0); - } if (data) - { - m_IsLoaded = true; - - m_Width = width; - m_Height = height; - - GLenum internalFormat = 0, dataFormat = 0; - if (channels == 4) - { - internalFormat = GL_RGBA8; - dataFormat = GL_RGBA; - } - else if (channels == 3) - { - internalFormat = GL_RGB8; - dataFormat = GL_RGB; - } - - m_InternalFormat = internalFormat; - m_DataFormat = dataFormat; - - SE_CORE_ASSERT(internalFormat & dataFormat, "Format not supported!"); - - glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID); - glTextureStorage2D(m_RendererID, 1, internalFormat, m_Width, m_Height); - - glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, dataFormat, GL_UNSIGNED_BYTE, data); - - stbi_image_free(data); - } + SetData(data); } OpenGLTexture2D::~OpenGLTexture2D() @@ -110,13 +61,13 @@ namespace StarEngine { glDeleteTextures(1, &m_RendererID); } - void OpenGLTexture2D::SetData(void* data, uint32_t size) + void OpenGLTexture2D::SetData(Buffer data) { SE_PROFILE_FUNCTION(); uint32_t bpp = m_DataFormat == GL_RGBA ? 4 : 3; - SE_CORE_ASSERT(size == m_Width * m_Height * bpp, "Data must be entire texture!"); - glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_DataFormat, GL_UNSIGNED_BYTE, data); + SE_CORE_ASSERT(data.Size == m_Width * m_Height * bpp, "Data must be entire texture!"); + glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_DataFormat, GL_UNSIGNED_BYTE, data.Data); } void OpenGLTexture2D::Bind(uint32_t slot) const diff --git a/StarEngine/src/Platform/OpenGL/OpenGLTexture.h b/StarEngine/src/Platform/OpenGL/OpenGLTexture.h index 7c74416..04ca081 100644 --- a/StarEngine/src/Platform/OpenGL/OpenGLTexture.h +++ b/StarEngine/src/Platform/OpenGL/OpenGLTexture.h @@ -9,8 +9,7 @@ namespace StarEngine { class OpenGLTexture2D : public Texture2D { public: - OpenGLTexture2D(const TextureSpecification& specification); - OpenGLTexture2D(const std::string& path); + OpenGLTexture2D(const TextureSpecification& specification, Buffer data = Buffer()); virtual ~OpenGLTexture2D(); virtual const TextureSpecification& GetSpecification() const override { return m_Specification; } @@ -19,9 +18,7 @@ namespace StarEngine { virtual uint32_t GetHeight() const override { return m_Height; } virtual uint32_t GetRendererID() const override { return m_RendererID; } - virtual const std::string& GetPath() const override { return m_Path; } - - virtual void SetData(void* data, uint32_t size) override; + virtual void SetData(Buffer data) override; virtual void Bind(uint32_t slot = 0) const override; @@ -34,7 +31,6 @@ namespace StarEngine { private: TextureSpecification m_Specification; - std::string m_Path; bool m_IsLoaded = false; uint32_t m_Width, m_Height; uint32_t m_RendererID; diff --git a/StarEngine/src/Platform/Windows/WindowsWindow.cpp b/StarEngine/src/Platform/Windows/WindowsWindow.cpp index bf71d81..9ac4ee6 100644 --- a/StarEngine/src/Platform/Windows/WindowsWindow.cpp +++ b/StarEngine/src/Platform/Windows/WindowsWindow.cpp @@ -171,6 +171,18 @@ namespace StarEngine { MouseMovedEvent event((float)xPos, (float)yPos); data.EventCallback(event); }); + + glfwSetDropCallback(m_Window, [](GLFWwindow* window, int pathCount, const char* paths[]) + { + WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); + + std::vector filepaths(pathCount); + for (int i = 0; i < pathCount; i++) + filepaths[i] = paths[i]; + + WindowDropEvent event(std::move(filepaths)); + data.EventCallback(event); + }); } void WindowsWindow::Shutdown() diff --git a/StarEngine/src/StarEngine/Asset/Asset.cpp b/StarEngine/src/StarEngine/Asset/Asset.cpp new file mode 100644 index 0000000..735df24 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/Asset.cpp @@ -0,0 +1,6 @@ +#include "sepch.h" +#include "Asset.h" + +namespace StarEngine { + +} diff --git a/StarEngine/src/StarEngine/Asset/Asset.h b/StarEngine/src/StarEngine/Asset/Asset.h new file mode 100644 index 0000000..8331a2d --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/Asset.h @@ -0,0 +1,23 @@ +#pragma once + +#include "StarEngine/Core/UUID.h" + +namespace StarEngine +{ + using AssetHandle = UUID; + + enum class AssetType : uint16_t + { + None = 0, + Scene, + Texture2D + }; + + class Asset + { + public: + AssetHandle Handle; // Generate handle + + virtual AssetType GetType() const = 0; + }; +} diff --git a/StarEngine/src/StarEngine/Asset/AssetImporter.cpp b/StarEngine/src/StarEngine/Asset/AssetImporter.cpp new file mode 100644 index 0000000..2fb84e5 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/AssetImporter.cpp @@ -0,0 +1,25 @@ +#include "sepch.h" +#include "AssetImporter.h" + +#include "TextureImporter.h" + +#include + +namespace StarEngine +{ + using AssetImportFunction = std::function(AssetHandle, const AssetMetadata&)>; + static std::map s_AssetImportFunctions = { + { AssetType::Texture2D, TextureImporter::ImportTexture2D } + }; + + Ref AssetImporter::ImportAsset(AssetHandle handle, const AssetMetadata& metadata) + { + if (s_AssetImportFunctions.find(metadata.Type) == s_AssetImportFunctions.end()) + { + SE_CORE_ERROR("No importer available for asset type: {}", (uint16_t)metadata.Type); + return nullptr; + } + + return s_AssetImportFunctions.at(metadata.Type)(handle, metadata); + } +} diff --git a/StarEngine/src/StarEngine/Asset/AssetImporter.h b/StarEngine/src/StarEngine/Asset/AssetImporter.h new file mode 100644 index 0000000..7dd75bf --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/AssetImporter.h @@ -0,0 +1,13 @@ +#pragma once + +#include "AssetMetadata.h" + +namespace StarEngine +{ + class AssetImporter + { + public: + static Ref ImportAsset(AssetHandle handle, const AssetMetadata& metadata); + }; + +} diff --git a/StarEngine/src/StarEngine/Asset/AssetManager.cpp b/StarEngine/src/StarEngine/Asset/AssetManager.cpp new file mode 100644 index 0000000..15c19c3 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/AssetManager.cpp @@ -0,0 +1,7 @@ +#include "sepch.h" +#include "AssetManager.h" + +namespace StarEngine +{ + +} diff --git a/StarEngine/src/StarEngine/Asset/AssetManager.h b/StarEngine/src/StarEngine/Asset/AssetManager.h new file mode 100644 index 0000000..fdc5dfd --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/AssetManager.h @@ -0,0 +1,19 @@ +#pragma once + +#include "AssetManagerBase.h" + +#include "StarEngine/Project/Project.h" + +namespace StarEngine +{ + class AssetManager + { + public: + template + static Ref GetAsset(AssetHandle handle) + { + Ref asset = Project::GetActive()->GetAssetManager()->GetAsset(handle); + return std::static_pointer_cast(asset); + } + }; +} diff --git a/StarEngine/src/StarEngine/Asset/AssetManagerBase.cpp b/StarEngine/src/StarEngine/Asset/AssetManagerBase.cpp new file mode 100644 index 0000000..15c19c3 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/AssetManagerBase.cpp @@ -0,0 +1,7 @@ +#include "sepch.h" +#include "AssetManager.h" + +namespace StarEngine +{ + +} diff --git a/StarEngine/src/StarEngine/Asset/AssetManagerBase.h b/StarEngine/src/StarEngine/Asset/AssetManagerBase.h new file mode 100644 index 0000000..fc7a184 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/AssetManagerBase.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Asset.h" + +#include + +namespace StarEngine +{ + using AssetMap = std::map>; + + class AssetManagerBase + { + public: + virtual Ref GetAsset(AssetHandle handle) const = 0; + + virtual bool IsAssetHandleValid(AssetHandle handle) const = 0; + virtual bool IsAssetLoaded(AssetHandle handle) const = 0; + }; +} diff --git a/StarEngine/src/StarEngine/Asset/AssetMetadata.h b/StarEngine/src/StarEngine/Asset/AssetMetadata.h new file mode 100644 index 0000000..4eeec58 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/AssetMetadata.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Asset.h" + +#include + +namespace StarEngine +{ + struct AssetMetadata + { + AssetType Type = AssetType::None; + std::filesystem::path FilePath; + + operator bool() const { return Type != AssetType::None; } + }; +} diff --git a/StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp b/StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp new file mode 100644 index 0000000..a3f2550 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp @@ -0,0 +1,55 @@ +#include "sepch.h" +#include "AssetManager.h" + +#include "AssetImporter.h" + +namespace StarEngine { + + bool EditorAssetManager::IsAssetHandleValid(AssetHandle handle) const + { + return handle != 0 && m_AssetRegistry.find(handle) != m_AssetRegistry.end(); + } + + bool EditorAssetManager::IsAssetLoaded(AssetHandle handle) const + { + return m_LoadedAssets.find(handle) != m_LoadedAssets.end(); + } + + const AssetMetadata& EditorAssetManager::GetMetadata(AssetHandle handle) const + { + static AssetMetadata s_NullMetadata; + auto it = m_AssetRegistry.find(handle); + if (it == m_AssetRegistry.end()) + return s_NullMetadata; + + return it->second; + } + + Ref EditorAssetManager::GetAsset(AssetHandle handle) const + { + // 1. check if handle is valid + if (!IsAssetHandleValid(handle)) + return nullptr; + + // 2. check if asset needs load (and if so, load) + Ref asset; + if (IsAssetLoaded(handle)) + { + asset = m_LoadedAssets.at(handle); + } + else + { + // load asset + const AssetMetadata& metadata = GetMetadata(handle); + asset = AssetImporter::ImportAsset(handle, metadata); + if (!asset) + { + // import failed + SE_CORE_ERROR("EditorAssetManager::GetAsset - asset import failed!"); + } + } + // 3. return asset + return asset; + } + +} diff --git a/StarEngine/src/StarEngine/Asset/EditorAssetManager.h b/StarEngine/src/StarEngine/Asset/EditorAssetManager.h new file mode 100644 index 0000000..756ecbe --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/EditorAssetManager.h @@ -0,0 +1,27 @@ +#pragma once + +#include "AssetManagerBase.h" +#include "AssetMetadata.h" + +#include + +namespace StarEngine { + + using AssetRegistry = std::map; + + class EditorAssetManager : public AssetManagerBase + { + public: + virtual Ref GetAsset(AssetHandle handle) const override; + + virtual bool IsAssetHandleValid(AssetHandle handle) const override; + virtual bool IsAssetLoaded(AssetHandle handle) const override; + + const AssetMetadata& GetMetadata(AssetHandle handle) const; + private: + AssetRegistry m_AssetRegistry; + AssetMap m_LoadedAssets; + + // TODO: memory-only assets + }; +} diff --git a/StarEngine/src/StarEngine/Asset/RuntimeAssetManager.cpp b/StarEngine/src/StarEngine/Asset/RuntimeAssetManager.cpp new file mode 100644 index 0000000..a724855 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/RuntimeAssetManager.cpp @@ -0,0 +1,7 @@ +#include "sepch.h" +#include "AssetManager.h" + +namespace StarEngine { + + +} diff --git a/StarEngine/src/StarEngine/Asset/RuntimeAssetManager.h b/StarEngine/src/StarEngine/Asset/RuntimeAssetManager.h new file mode 100644 index 0000000..e004620 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/RuntimeAssetManager.h @@ -0,0 +1,11 @@ +#pragma once + +#include "AssetManagerBase.h" + +namespace StarEngine { + + class RuntimeAssetManager : public AssetManagerBase + { + public: + }; +} diff --git a/StarEngine/src/StarEngine/Asset/TextureImporter.cpp b/StarEngine/src/StarEngine/Asset/TextureImporter.cpp new file mode 100644 index 0000000..e28638d --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/TextureImporter.cpp @@ -0,0 +1,50 @@ +#include "sepch.h" +#include "TextureImporter.h" + +#include + +namespace StarEngine { + + Ref TextureImporter::ImportTexture2D(AssetHandle handle, const AssetMetadata& metadata) + { + SE_PROFILE_FUNCTION(); + + int width, height, channels; + stbi_set_flip_vertically_on_load(1); + Buffer data; + + { + SE_PROFILE_SCOPE("stbi_load - TextureImporter::ImportTexture2D"); + std::string pathStr = metadata.FilePath.string(); + data.Data = stbi_load(pathStr.c_str(), &width, &height, &channels, 0); + } + + if (data.Data == nullptr) + { + SE_CORE_ERROR("TextureImporter::ImportTexture2D - Could not load texture from filepath: {}", metadata.FilePath.string()); + return nullptr; + } + + // TODO: think about this + data.Size = width * height * channels; + + TextureSpecification spec; + spec.Width = width; + spec.Height = height; + switch (channels) + { + case 3: + spec.Format = ImageFormat::RGB8; + break; + case 4: + spec.Format = ImageFormat::RGBA8; + break; + } + + Ref texture = Texture2D::Create(spec, data); + data.Release(); + return texture; + } + + +} diff --git a/StarEngine/src/StarEngine/Asset/TextureImporter.h b/StarEngine/src/StarEngine/Asset/TextureImporter.h new file mode 100644 index 0000000..3d345f3 --- /dev/null +++ b/StarEngine/src/StarEngine/Asset/TextureImporter.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Asset.h" +#include "AssetMetadata.h" + +#include "StarEngine/Renderer/Texture.h" + +namespace StarEngine { + + class TextureImporter + { + public: + static Ref ImportTexture2D(AssetHandle handle, const AssetMetadata& metadata); + }; +} diff --git a/StarEngine/src/StarEngine/Core/Buffer.h b/StarEngine/src/StarEngine/Core/Buffer.h index 21b3955..9cccb7c 100644 --- a/StarEngine/src/StarEngine/Core/Buffer.h +++ b/StarEngine/src/StarEngine/Core/Buffer.h @@ -17,6 +17,11 @@ namespace StarEngine { Allocate(size); } + Buffer(const void* data, uint64_t size) + : Data((uint8_t*)data), Size(size) + { + } + Buffer(const Buffer&) = default; static Buffer Copy(Buffer other) @@ -30,13 +35,13 @@ namespace StarEngine { { Release(); - Data = new uint8_t[size]; + Data = (uint8_t*)malloc(size); Size = size; } void Release() { - delete[] Data; + free(Data); Data = nullptr; Size = 0; } diff --git a/StarEngine/src/StarEngine/Events/ApplicationEvent.h b/StarEngine/src/StarEngine/Events/ApplicationEvent.h index b19819d..bf08145 100644 --- a/StarEngine/src/StarEngine/Events/ApplicationEvent.h +++ b/StarEngine/src/StarEngine/Events/ApplicationEvent.h @@ -62,4 +62,23 @@ namespace StarEngine { EVENT_CLASS_TYPE(AppRender) EVENT_CLASS_CATEGORY(EventCategoryApplication) }; -} \ No newline at end of file + + class WindowDropEvent : public Event + { + public: + WindowDropEvent(const std::vector& paths) + : m_Paths(paths) { + } + + WindowDropEvent(std::vector&& paths) + : m_Paths(std::move(paths)) { + } + + const std::vector& GetPaths() const { return m_Paths; } + + EVENT_CLASS_TYPE(WindowDrop) + EVENT_CLASS_CATEGORY(EventCategoryApplication) + private: + std::vector m_Paths; + }; +} diff --git a/StarEngine/src/StarEngine/Events/Event.h b/StarEngine/src/StarEngine/Events/Event.h index 846ac5d..3541817 100644 --- a/StarEngine/src/StarEngine/Events/Event.h +++ b/StarEngine/src/StarEngine/Events/Event.h @@ -15,7 +15,7 @@ namespace StarEngine { enum class EventType { None = 0, - WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved, + WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved, WindowDrop, AppTick, AppUpdate, AppRender, KeyPressed, KeyReleased, KeyTyped, MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled diff --git a/StarEngine/src/StarEngine/Project/Project.h b/StarEngine/src/StarEngine/Project/Project.h index 0fbbb6c..826adae 100644 --- a/StarEngine/src/StarEngine/Project/Project.h +++ b/StarEngine/src/StarEngine/Project/Project.h @@ -5,6 +5,9 @@ #include "StarEngine/Core/Base.h" +#include "StarEngine/Asset/RuntimeAssetManager.h" +#include "StarEngine/Asset/EditorAssetManager.h" + namespace StarEngine { struct ProjectConfig @@ -42,6 +45,9 @@ namespace StarEngine { ProjectConfig& GetConfig() { return m_Config; } static Ref GetActive() { return s_ActiveProject; } + Ref GetAssetManager() { return m_AssetManager; } + Ref GetRuntimeAssetManager() { return std::static_pointer_cast(m_AssetManager); } + Ref GetEditorAssetManager() { return std::static_pointer_cast(m_AssetManager); } static Ref New(); static Ref Load(const std::filesystem::path& path); @@ -49,6 +55,7 @@ namespace StarEngine { private: ProjectConfig m_Config; std::filesystem::path m_ProjectDirectory; + Ref m_AssetManager; inline static Ref s_ActiveProject; }; diff --git a/StarEngine/src/StarEngine/Renderer/Font.cpp b/StarEngine/src/StarEngine/Renderer/Font.cpp index 707e022..7f87238 100644 --- a/StarEngine/src/StarEngine/Renderer/Font.cpp +++ b/StarEngine/src/StarEngine/Renderer/Font.cpp @@ -32,7 +32,7 @@ namespace StarEngine { spec.GenerateMips = false; Ref texture = Texture2D::Create(spec); - texture->SetData((void*)bitmap.pixels, bitmap.width * bitmap.height * 3); + texture->SetData(Buffer((void*)bitmap.pixels, bitmap.width * bitmap.height * 3)); return texture; } diff --git a/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp b/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp index 332f573..1ca24f7 100644 --- a/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp +++ b/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp @@ -201,7 +201,7 @@ namespace StarEngine { s_Data.WhiteTexture = Texture2D::Create(TextureSpecification()); uint32_t whiteTextureData = 0xffffffff; - s_Data.WhiteTexture->SetData(&whiteTextureData, sizeof(uint32_t)); + s_Data.WhiteTexture->SetData(Buffer(&whiteTextureData, sizeof(uint32_t))); int32_t samplers[s_Data.MaxTextureSlots]; for (uint32_t i = 0; i < s_Data.MaxTextureSlots; i++) diff --git a/StarEngine/src/StarEngine/Renderer/Texture.cpp b/StarEngine/src/StarEngine/Renderer/Texture.cpp index 1efc3a2..5482333 100644 --- a/StarEngine/src/StarEngine/Renderer/Texture.cpp +++ b/StarEngine/src/StarEngine/Renderer/Texture.cpp @@ -6,24 +6,12 @@ namespace StarEngine { - Ref Texture2D::Create(const TextureSpecification& specification) + Ref Texture2D::Create(const TextureSpecification& specification, Buffer data) { switch (Renderer::GetAPI()) { case RendererAPI::API::None: SE_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr; - case RendererAPI::API::OpenGL: return CreateRef(specification); - } - - SE_CORE_ASSERT(false, "Unknown RendererAPI!"); - return nullptr; - } - - Ref Texture2D::Create(const std::string& path) - { - switch (Renderer::GetAPI()) - { - case RendererAPI::API::None: SE_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr; - case RendererAPI::API::OpenGL: return CreateRef(path); + case RendererAPI::API::OpenGL: return CreateRef(specification, data); } SE_CORE_ASSERT(false, "Unknown RendererAPI!"); diff --git a/StarEngine/src/StarEngine/Renderer/Texture.h b/StarEngine/src/StarEngine/Renderer/Texture.h index 08676ff..c60ddf8 100644 --- a/StarEngine/src/StarEngine/Renderer/Texture.h +++ b/StarEngine/src/StarEngine/Renderer/Texture.h @@ -1,9 +1,13 @@ #pragma once #include "StarEngine/Core/Base.h" +#include "StarEngine/Core/Buffer.h" + +#include "StarEngine/Asset/Asset.h" #include + namespace StarEngine { enum class ImageFormat @@ -23,7 +27,7 @@ namespace StarEngine { bool GenerateMips = true; }; - class Texture + class Texture : public Asset { public: virtual ~Texture() = default; @@ -34,9 +38,7 @@ namespace StarEngine { virtual uint32_t GetHeight() const = 0; virtual uint32_t GetRendererID() const = 0; - virtual const std::string& GetPath() const = 0; - - virtual void SetData(void* data, uint32_t size) = 0; + virtual void SetData(Buffer data) = 0; virtual void Bind(uint32_t slot = 0) const = 0; @@ -48,8 +50,9 @@ namespace StarEngine { class Texture2D : public Texture { public: - static Ref Create(const TextureSpecification& specification); - static Ref Create(const std::string& path); - }; + static Ref Create(const TextureSpecification& specification, Buffer data = Buffer()); + static AssetType GetStaticType() { return AssetType::Texture2D; } + virtual AssetType GetType() const { return GetStaticType(); } + }; } diff --git a/StarEngine/src/sepch.h b/StarEngine/src/sepch.h index 4a8bf2d..e946feb 100644 --- a/StarEngine/src/sepch.h +++ b/StarEngine/src/sepch.h @@ -24,10 +24,12 @@ #include "StarEngine/Core/Base.h" +#include "StarEngine/Core/Buffer.h" + #include "StarEngine/Core/Log.h" #include "StarEngine/Debug/Instrumentor.h" #ifdef SE_PLATFORM_WINDOWS #include -#endif \ No newline at end of file +#endif From 3105249b0592a300db7b3995230bbeefa6173a55 Mon Sep 17 00:00:00 2001 From: Pier-Olivier Boulianne Date: Sun, 18 May 2025 17:55:14 -0400 Subject: [PATCH 2/9] Asset Manager WIP - Texture importing - Changed SpriteRendererComponent to use asset handles - Added Asset Registry including serialization - Content Browser work to add Asset mode - Added AssetRegistryPath to Project config --- Sandbox/src/ExampleLayer.cpp | 6 +- Sandbox/src/Sandbox2D.cpp | 4 +- .../SandboxProject/Assets/AssetRegistry.ser | 4 + .../Assets/Scenes/Physics2D.starscene | 119 +++++++------ StarEditor/SandboxProject/Sandbox.starproj | 1 + StarEditor/src/EditorLayer.cpp | 14 +- StarEditor/src/Panels/ContentBrowserPanel.cpp | 166 +++++++++++++++--- StarEditor/src/Panels/ContentBrowserPanel.h | 31 +++- StarEditor/src/Panels/SceneHierarchyPanel.cpp | 4 +- StarEngine/src/StarEngine/Asset/Asset.cpp | 21 +++ StarEngine/src/StarEngine/Asset/Asset.h | 5 +- .../src/StarEngine/Asset/AssetImporter.h | 1 + .../StarEngine/Asset/EditorAssetManager.cpp | 93 ++++++++++ .../src/StarEngine/Asset/EditorAssetManager.h | 7 + .../src/StarEngine/Asset/TextureImporter.cpp | 15 +- .../src/StarEngine/Asset/TextureImporter.h | 5 + StarEngine/src/StarEngine/Core/Assert.h | 20 ++- StarEngine/src/StarEngine/Core/Base.h | 13 +- StarEngine/src/StarEngine/Project/Project.cpp | 3 + StarEngine/src/StarEngine/Project/Project.h | 7 + .../StarEngine/Project/ProjectSerializer.cpp | 16 +- .../StarEngine/Project/ProjectSerializer.h | 4 +- .../src/StarEngine/Renderer/Renderer2D.cpp | 6 +- StarEngine/src/StarEngine/Scene/Components.h | 2 +- .../src/StarEngine/Scene/SceneSerializer.cpp | 13 +- .../mono/lib/Dist/libmono-static-sgen.lib | Bin 0 -> 33872520 bytes 26 files changed, 452 insertions(+), 128 deletions(-) create mode 100644 StarEditor/SandboxProject/Assets/AssetRegistry.ser create mode 100644 StarEngine/vendor/mono/lib/Dist/libmono-static-sgen.lib diff --git a/Sandbox/src/ExampleLayer.cpp b/Sandbox/src/ExampleLayer.cpp index a5f2ac4..be9ffbc 100644 --- a/Sandbox/src/ExampleLayer.cpp +++ b/Sandbox/src/ExampleLayer.cpp @@ -7,6 +7,8 @@ #include "StarEngine.h" +#include "StarEngine/Asset/TextureImporter.h" + ExampleLayer::ExampleLayer() : Layer("ExampleLayer"), m_CameraController(1280.0f / 720.0f) { @@ -113,8 +115,8 @@ ExampleLayer::ExampleLayer() m_FlatColorShader = StarEngine::Shader::Create("FlatColor", flatColorShaderVertexSrc, flatColorShaderFragmentSrc); auto textureShader = m_ShaderLibrary.Load("assets/shaders/Texture.glsl"); - m_Texture = StarEngine::Texture2D::Create("assets/textures/Checkerboard.png"); - m_starLogoTexture = StarEngine::Texture2D::Create("assets/textures/starLogo.png"); + m_Texture = StarEngine::TextureImporter::LoadTexture2D("assets/textures/Checkerboard.png"); + m_starLogoTexture = StarEngine::TextureImporter::LoadTexture2D("assets/textures/starLogo.png"); textureShader->Bind(); textureShader->SetInt("u_Texture", 0); diff --git a/Sandbox/src/Sandbox2D.cpp b/Sandbox/src/Sandbox2D.cpp index f6a8b8e..bfdf3c7 100644 --- a/Sandbox/src/Sandbox2D.cpp +++ b/Sandbox/src/Sandbox2D.cpp @@ -7,6 +7,8 @@ #include "imgui/imgui_internal.h" +#include "StarEngine/Asset/TextureImporter.h" + Sandbox2D::Sandbox2D() :Layer("Sandbox2D"), m_CameraController(1280.0f / 720.0f, true), m_SquareColor({ 0.2f, 0.3f, 0.8f, 1.0f }) @@ -18,7 +20,7 @@ void Sandbox2D::OnAttach() { SE_PROFILE_FUNCTION(); - m_CheckerboardTexture = StarEngine::Texture2D::Create("assets/textures/Checkerboard.png"); + m_CheckerboardTexture = StarEngine::TextureImporter::LoadTexture2D("assets/textures/Checkerboard.png"); } void Sandbox2D::OnDetach() diff --git a/StarEditor/SandboxProject/Assets/AssetRegistry.ser b/StarEditor/SandboxProject/Assets/AssetRegistry.ser new file mode 100644 index 0000000..aa9c164 --- /dev/null +++ b/StarEditor/SandboxProject/Assets/AssetRegistry.ser @@ -0,0 +1,4 @@ +AssetRegistry: + - Handle: 9263618904997247981 + FilePath: Textures/starLogo.png + Type: AssetType::Texture2D \ No newline at end of file diff --git a/StarEditor/SandboxProject/Assets/Scenes/Physics2D.starscene b/StarEditor/SandboxProject/Assets/Scenes/Physics2D.starscene index 16f8b62..87f8194 100644 --- a/StarEditor/SandboxProject/Assets/Scenes/Physics2D.starscene +++ b/StarEditor/SandboxProject/Assets/Scenes/Physics2D.starscene @@ -1,37 +1,64 @@ Scene: Untitled Entities: - - Entity: 12327645238897851592 + - Entity: 14040563719264005740 TagComponent: - Tag: Welcome + Tag: Player TransformComponent: - Translation: [-3.79999995, 1.79999995, 0] + Translation: [0, 5, 0] Rotation: [0, 0, 0] Scale: [1, 1, 1] - TextComponent: - TextString: Welcome to StarEditor + SpriteRendererComponent: Color: [1, 1, 1, 1] - Kerning: 0 - LineSpacing: 0 - - Entity: 6793217508611625246 + TextureHandle: 0 + TilingFactor: 1 + RigidBody2DComponent: + BodyType: Dynamic + FixedRotation: false + BoxCollider2DComponent: + Offset: [0, 0] + Size: [0.5, 0.5] + Density: 1 + Friction: 0.5 + Restitution: 0 + RestitutionThreshold: 0.5 + - Entity: 16241606122818465121 TagComponent: - Tag: Circle + Tag: Camera TransformComponent: Translation: [0, 0, 0] Rotation: [0, 0, 0] Scale: [1, 1, 1] - CircleRendererComponent: - Color: [0.934362948, 0.497845858, 0, 1] - Thickness: 1 - Fade: 0.00499999989 + CameraComponent: + Camera: + ProjectionType: 1 + PerspectiveFOV: 0.785398185 + PerspectiveNear: 0.00999999978 + PerspectiveFar: 1000 + OrthographicSize: 25 + OrthographicNear: -1 + OrthographicFar: 1 + Primary: true + FixedAspectRatio: false + - Entity: 16059016071823036758 + TagComponent: + Tag: Cube + TransformComponent: + Translation: [0, 10, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + SpriteRendererComponent: + Color: [1, 1, 1, 1] + TextureHandle: 0 + TilingFactor: 1 RigidBody2DComponent: BodyType: Dynamic FixedRotation: false - CircleCollider2DComponent: + BoxCollider2DComponent: Offset: [0, 0] - Radius: 0.5 + Size: [0.5, 0.5] Density: 1 Friction: 0.5 - Restitution: 1 + Restitution: 0.100000001 RestitutionThreshold: 0.5 - Entity: 7665505456185074185 TagComponent: @@ -42,6 +69,7 @@ Entities: Scale: [10, 1, 1] SpriteRendererComponent: Color: [1, 1, 1, 1] + TextureHandle: 0 TilingFactor: 1 RigidBody2DComponent: BodyType: Static @@ -53,61 +81,36 @@ Entities: Friction: 0.5 Restitution: 0 RestitutionThreshold: 0.5 - - Entity: 16059016071823036758 + - Entity: 6793217508611625246 TagComponent: - Tag: Cube + Tag: Circle TransformComponent: - Translation: [0, 10, 0] + Translation: [0, 0, 0] Rotation: [0, 0, 0] Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - TilingFactor: 1 + CircleRendererComponent: + Color: [0.934362948, 0.497845858, 0, 1] + Thickness: 1 + Fade: 0.00499999989 RigidBody2DComponent: BodyType: Dynamic FixedRotation: false - BoxCollider2DComponent: + CircleCollider2DComponent: Offset: [0, 0] - Size: [0.5, 0.5] + Radius: 0.5 Density: 1 Friction: 0.5 - Restitution: 0.100000001 + Restitution: 1 RestitutionThreshold: 0.5 - - Entity: 16241606122818465121 - TagComponent: - Tag: Camera - TransformComponent: - Translation: [0, 0, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - CameraComponent: - Camera: - ProjectionType: 1 - PerspectiveFOV: 0.785398185 - PerspectiveNear: 0.00999999978 - PerspectiveFar: 1000 - OrthographicSize: 25 - OrthographicNear: -1 - OrthographicFar: 1 - Primary: true - FixedAspectRatio: false - - Entity: 14040563719264005740 + - Entity: 12327645238897851592 TagComponent: - Tag: Player + Tag: Welcome TransformComponent: - Translation: [0, 5, 0] + Translation: [-3.79999995, 1.79999995, 0] Rotation: [0, 0, 0] Scale: [1, 1, 1] - SpriteRendererComponent: + TextComponent: + TextString: Welcome to StarEditor Color: [1, 1, 1, 1] - TilingFactor: 1 - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Restitution: 0 - RestitutionThreshold: 0.5 \ No newline at end of file + Kerning: 0 + LineSpacing: 0 \ No newline at end of file diff --git a/StarEditor/SandboxProject/Sandbox.starproj b/StarEditor/SandboxProject/Sandbox.starproj index b128b22..c51ed1a 100644 --- a/StarEditor/SandboxProject/Sandbox.starproj +++ b/StarEditor/SandboxProject/Sandbox.starproj @@ -2,4 +2,5 @@ Project: Name: Sandbox StartScene: "Scenes/Physics2D.starscene" AssetDirectory: "Assets" + AssetRegistryPath: "AssetRegistry.ser" ScriptModulePath: "Scripts/Binaries/Sandbox.dll" diff --git a/StarEditor/src/EditorLayer.cpp b/StarEditor/src/EditorLayer.cpp index a8896d0..0e19676 100644 --- a/StarEditor/src/EditorLayer.cpp +++ b/StarEditor/src/EditorLayer.cpp @@ -6,6 +6,8 @@ #include "StarEngine/Scripting/ScriptEngine.h" #include "StarEngine/Renderer/Font.h" +#include "StarEngine/Asset/TextureImporter.h" + #include #include @@ -29,13 +31,11 @@ namespace StarEngine { { SE_PROFILE_FUNCTION(); - m_CheckerboardTexture = Texture2D::Create("assets/textures/Checkerboard.png"); - - m_IconPlay = Texture2D::Create("Resources/Icons/PlayButton.png"); - m_IconPause = Texture2D::Create("Resources/Icons/PauseButton.png"); - m_IconSimulate = Texture2D::Create("Resources/Icons/SimulateButton.png"); - m_IconStep = Texture2D::Create("Resources/Icons/StepButton.png"); - m_IconStop = Texture2D::Create("Resources/Icons/StopButton.png"); + m_IconPlay = TextureImporter::LoadTexture2D("Resources/Icons/PlayButton.png"); + m_IconPause = TextureImporter::LoadTexture2D("Resources/Icons/PauseButton.png"); + m_IconSimulate = TextureImporter::LoadTexture2D("Resources/Icons/SimulateButton.png"); + m_IconStep = TextureImporter::LoadTexture2D("Resources/Icons/StepButton.png"); + m_IconStop = TextureImporter::LoadTexture2D("Resources/Icons/StopButton.png"); FramebufferSpecification fbSpec; fbSpec.Attachments = { FramebufferTextureFormat::RGBA8, FramebufferTextureFormat::RED_INTEGER, FramebufferTextureFormat::Depth }; diff --git a/StarEditor/src/Panels/ContentBrowserPanel.cpp b/StarEditor/src/Panels/ContentBrowserPanel.cpp index 56fb25c..17376c0 100644 --- a/StarEditor/src/Panels/ContentBrowserPanel.cpp +++ b/StarEditor/src/Panels/ContentBrowserPanel.cpp @@ -2,30 +2,45 @@ #include "ContentBrowserPanel.h" #include "StarEngine/Project/Project.h" +#include "StarEngine/Asset/TextureImporter.h" #include -namespace StarEngine -{ +namespace StarEngine { + ContentBrowserPanel::ContentBrowserPanel() : m_BaseDirectory(Project::GetAssetDirectory()), m_CurrentDirectory(m_BaseDirectory) { - m_DirectoryIcon = Texture2D::Create("Resources/Icons/ContentBrowser/DirectoryIcon.png"); - m_FileIcon = Texture2D::Create("Resources/Icons/ContentBrowser/FileIcon.png"); + m_TreeNodes.push_back(TreeNode(".")); + + m_DirectoryIcon = TextureImporter::LoadTexture2D("Resources/Icons/ContentBrowser/DirectoryIcon.png"); + m_FileIcon = TextureImporter::LoadTexture2D("Resources/Icons/ContentBrowser/FileIcon.png"); + + RefreshAssetTree(); + + m_Mode = Mode::FileSystem; } void ContentBrowserPanel::OnImGuiRender() { ImGui::Begin("Content Browser"); + const char* label = m_Mode == Mode::Asset ? "Asset" : "File"; + if (ImGui::Button(label)) + { + m_Mode = m_Mode == Mode::Asset ? Mode::FileSystem : Mode::Asset; + } + if (m_CurrentDirectory != std::filesystem::path(m_BaseDirectory)) { + ImGui::SameLine(); if (ImGui::Button("<-")) { m_CurrentDirectory = m_CurrentDirectory.parent_path(); } } + static float padding = 16.0f; static float thumbnailSize = 128.0f; float cellSize = thumbnailSize + padding; @@ -37,36 +52,108 @@ namespace StarEngine ImGui::Columns(columnCount, 0, false); - for (auto& directoryEntry : std::filesystem::directory_iterator(m_CurrentDirectory)) + if (m_Mode == Mode::Asset) { - const auto& path = directoryEntry.path(); - std::string filenameString = path.filename().string(); + TreeNode* node = &m_TreeNodes[0]; - ImGui::PushID(filenameString.c_str()); - Ref icon = directoryEntry.is_directory() ? m_DirectoryIcon : m_FileIcon; - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); - ImGui::ImageButton("##icon", (ImTextureID)icon->GetRendererID(), { thumbnailSize, thumbnailSize }, { 0, 1 }, { 1, 0 }); - - if (ImGui::BeginDragDropSource()) + auto currentDir = std::filesystem::relative(m_CurrentDirectory, Project::GetAssetDirectory()); + for (const auto& p : currentDir) { - std::filesystem::path relativePath(path); - const wchar_t* itemPath = relativePath.c_str(); - ImGui::SetDragDropPayload("CONTENT_BROWSER_ITEM", itemPath, (wcslen(itemPath) + 1) * sizeof(wchar_t)); - ImGui::EndDragDropSource(); + // if only one level + if (node->Path == currentDir) + break; + + if (node->Children.find(p) != node->Children.end()) + { + node = &m_TreeNodes[node->Children[p]]; + continue; + } + else + { + // can't find path + SE_CORE_ASSERT(false); + } + } - ImGui::PopStyleColor(); - if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) + for (const auto& [item, treeNodeIndex] : node->Children) { - if (directoryEntry.is_directory()) - m_CurrentDirectory /= path.filename(); + bool isDirectory = std::filesystem::is_directory(Project::GetAssetDirectory() / item); - } - ImGui::TextWrapped(filenameString.c_str()); + std::string itemStr = item.generic_string(); + + ImGui::PushID(itemStr.c_str()); + Ref icon = isDirectory ? m_DirectoryIcon : m_FileIcon; + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + ImGui::ImageButton("##icon", (ImTextureID)icon->GetRendererID(), { thumbnailSize, thumbnailSize }, { 0, 1 }, { 1, 0 }); + + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::MenuItem("Import")) + { + auto relativePath = std::filesystem::relative(item, Project::GetAssetDirectory()); + Project::GetActive()->GetEditorAssetManager()->ImportAsset(relativePath); + } + ImGui::EndPopup(); + } + + ImGui::PopStyleColor(); + if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) + { + if (isDirectory) + m_CurrentDirectory /= item.filename(); + } + + ImGui::TextWrapped(itemStr.c_str()); - ImGui::NextColumn(); + ImGui::NextColumn(); - ImGui::PopID(); + ImGui::PopID(); + } + } + else + { + for (auto& directoryEntry : std::filesystem::directory_iterator(m_CurrentDirectory)) + { + const auto& path = directoryEntry.path(); + std::string filenameString = path.filename().string(); + + ImGui::PushID(filenameString.c_str()); + Ref icon = directoryEntry.is_directory() ? m_DirectoryIcon : m_FileIcon; + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + ImGui::ImageButton("##icon", (ImTextureID)icon->GetRendererID(), { thumbnailSize, thumbnailSize }, { 0, 1 }, { 1, 0 }); + + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::MenuItem("Import")) + { + auto relativePath = std::filesystem::relative(path, Project::GetAssetDirectory()); + Project::GetActive()->GetEditorAssetManager()->ImportAsset(relativePath); + } + ImGui::EndPopup(); + } + + if (ImGui::BeginDragDropSource()) + { + std::filesystem::path relativePath(path); + const wchar_t* itemPath = relativePath.c_str(); + ImGui::SetDragDropPayload("CONTENT_BROWSER_ITEM", itemPath, (wcslen(itemPath) + 1) * sizeof(wchar_t)); + ImGui::EndDragDropSource(); + } + + ImGui::PopStyleColor(); + if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) + { + if (directoryEntry.is_directory()) + m_CurrentDirectory /= path.filename(); + } + + ImGui::TextWrapped(filenameString.c_str()); + + ImGui::NextColumn(); + + ImGui::PopID(); + } } ImGui::Columns(1); @@ -78,4 +165,33 @@ namespace StarEngine ImGui::End(); } + void ContentBrowserPanel::RefreshAssetTree() + { + const auto& assetRegistry = Project::GetActive()->GetEditorAssetManager()->GetAssetRegistry(); + for (const auto& [handle, metadata] : assetRegistry) + { + uint32_t currentNodeIndex = 0; + + for (const auto& p : metadata.FilePath) + { + auto it = m_TreeNodes[currentNodeIndex].Children.find(p.generic_string()); + if (it != m_TreeNodes[currentNodeIndex].Children.end()) + { + currentNodeIndex = it->second; + } + else + { + // add node + TreeNode newNode(p); + newNode.Parent = currentNodeIndex; + m_TreeNodes.push_back(newNode); + + m_TreeNodes[currentNodeIndex].Children[p] = m_TreeNodes.size() - 1; + currentNodeIndex = m_TreeNodes.size() - 1; + } + + } + } + } + } diff --git a/StarEditor/src/Panels/ContentBrowserPanel.h b/StarEditor/src/Panels/ContentBrowserPanel.h index c30c24c..bd46363 100644 --- a/StarEditor/src/Panels/ContentBrowserPanel.h +++ b/StarEditor/src/Panels/ContentBrowserPanel.h @@ -2,22 +2,49 @@ #include "StarEngine/Renderer/Texture.h" +#include +#include #include -namespace StarEngine -{ +namespace StarEngine { + class ContentBrowserPanel { public: ContentBrowserPanel(); void OnImGuiRender(); + private: + void RefreshAssetTree(); private: std::filesystem::path m_BaseDirectory; std::filesystem::path m_CurrentDirectory; Ref m_DirectoryIcon; Ref m_FileIcon; + + struct TreeNode + { + std::filesystem::path Path; + + uint32_t Parent = (uint32_t)-1; + std::map Children; + + TreeNode(const std::filesystem::path& path) + : Path(path) { + } + }; + + std::vector m_TreeNodes; + + std::map> m_AssetTree; + + enum class Mode + { + Asset = 0, FileSystem = 1 + }; + + Mode m_Mode = Mode::Asset; }; } diff --git a/StarEditor/src/Panels/SceneHierarchyPanel.cpp b/StarEditor/src/Panels/SceneHierarchyPanel.cpp index f9cec34..e4e575c 100644 --- a/StarEditor/src/Panels/SceneHierarchyPanel.cpp +++ b/StarEditor/src/Panels/SceneHierarchyPanel.cpp @@ -410,13 +410,15 @@ namespace StarEngine { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROWSER_ITEM")) { +#if 0 const wchar_t* path = (const wchar_t*)payload->Data; std::filesystem::path texturePath(path); Ref texture = Texture2D::Create(texturePath.string()); if (texture->IsLoaded()) - component.Texture = texture; + component.Texture = texture->Handle; else SE_WARN("Could not load texture {0}", texturePath.filename().string()); +#endif } ImGui::EndDragDropTarget(); } diff --git a/StarEngine/src/StarEngine/Asset/Asset.cpp b/StarEngine/src/StarEngine/Asset/Asset.cpp index 735df24..a0aa960 100644 --- a/StarEngine/src/StarEngine/Asset/Asset.cpp +++ b/StarEngine/src/StarEngine/Asset/Asset.cpp @@ -3,4 +3,25 @@ namespace StarEngine { + std::string_view AssetTypeToString(AssetType type) + { + switch (type) + { + case AssetType::None: return "AssetType::None"; + case AssetType::Scene: return "AssetType::Scene"; + case AssetType::Texture2D: return "AssetType::Texture2D"; + } + + return "AssetType::"; + } + + AssetType AssetTypeFromString(std::string_view assetType) + { + if (assetType == "AssetType::None") return AssetType::None; + if (assetType == "AssetType::Scene") return AssetType::Scene; + if (assetType == "AssetType::Texture2D") return AssetType::Texture2D; + + return AssetType::None; + } + } diff --git a/StarEngine/src/StarEngine/Asset/Asset.h b/StarEngine/src/StarEngine/Asset/Asset.h index 8331a2d..ceff455 100644 --- a/StarEngine/src/StarEngine/Asset/Asset.h +++ b/StarEngine/src/StarEngine/Asset/Asset.h @@ -12,7 +12,10 @@ namespace StarEngine Scene, Texture2D }; - + + std::string_view AssetTypeToString(AssetType type); + AssetType AssetTypeFromString(std::string_view assetType); + class Asset { public: diff --git a/StarEngine/src/StarEngine/Asset/AssetImporter.h b/StarEngine/src/StarEngine/Asset/AssetImporter.h index 7dd75bf..da03781 100644 --- a/StarEngine/src/StarEngine/Asset/AssetImporter.h +++ b/StarEngine/src/StarEngine/Asset/AssetImporter.h @@ -10,4 +10,5 @@ namespace StarEngine static Ref ImportAsset(AssetHandle handle, const AssetMetadata& metadata); }; + } diff --git a/StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp b/StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp index a3f2550..d7d89e6 100644 --- a/StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp +++ b/StarEngine/src/StarEngine/Asset/EditorAssetManager.cpp @@ -3,8 +3,29 @@ #include "AssetImporter.h" +#include +#include + +#include +#include + +namespace fmt { + template <> + struct formatter : formatter { + auto format(const std::filesystem::path& path, format_context& ctx) const { + return formatter::format(path.string(), ctx); + } + }; +} // namespace fmt + namespace StarEngine { + YAML::Emitter& operator<<(YAML::Emitter& out, const std::string_view& v) + { + out << std::string(v.data(), v.size()); + return out; + } + bool EditorAssetManager::IsAssetHandleValid(AssetHandle handle) const { return handle != 0 && m_AssetRegistry.find(handle) != m_AssetRegistry.end(); @@ -15,6 +36,22 @@ namespace StarEngine { return m_LoadedAssets.find(handle) != m_LoadedAssets.end(); } + void EditorAssetManager::ImportAsset(const std::filesystem::path& filepath) + { + AssetHandle handle; // generate new handle + AssetMetadata metadata; + metadata.FilePath = filepath; + metadata.Type = AssetType::Texture2D; // TODO(Yan): grab this from extension and try to load + Ref asset = AssetImporter::ImportAsset(handle, metadata); + asset->Handle = handle; + if (asset) + { + m_LoadedAssets[handle] = asset; + m_AssetRegistry[handle] = metadata; + SerializeAssetRegistry(); + } + } + const AssetMetadata& EditorAssetManager::GetMetadata(AssetHandle handle) const { static AssetMetadata s_NullMetadata; @@ -52,4 +89,60 @@ namespace StarEngine { return asset; } + void EditorAssetManager::SerializeAssetRegistry() + { + auto path = Project::GetAssetRegistryPath(); + + YAML::Emitter out; + { + out << YAML::BeginMap; // Root + out << YAML::Key << "AssetRegistry" << YAML::Value; + + out << YAML::BeginSeq; + for (const auto& [handle, metadata] : m_AssetRegistry) + { + out << YAML::BeginMap; + out << YAML::Key << "Handle" << YAML::Value << handle; + std::string filepathStr = metadata.FilePath.generic_string(); + out << YAML::Key << "FilePath" << YAML::Value << filepathStr; + out << YAML::Key << "Type" << YAML::Value << AssetTypeToString(metadata.Type); + out << YAML::EndMap; + } + out << YAML::EndSeq; + out << YAML::EndMap; // Root + } + + std::ofstream fout(path); + fout << out.c_str(); + + } + + bool EditorAssetManager::DeserializeAssetRegistry() + { + auto path = Project::GetAssetRegistryPath(); + YAML::Node data; + try + { + data = YAML::LoadFile(path.string()); + } + catch (YAML::ParserException e) + { + SE_CORE_ERROR("Failed to load project file '{0}'\n {1}", path, e.what()); + return false; + } + + auto rootNode = data["AssetRegistry"]; + if (!rootNode) + return false; + + for (const auto& node : rootNode) + { + AssetHandle handle = node["Handle"].as(); + auto& metadata = m_AssetRegistry[handle]; + metadata.FilePath = node["FilePath"].as(); + metadata.Type = AssetTypeFromString(node["Type"].as()); + } + + return true; + } } diff --git a/StarEngine/src/StarEngine/Asset/EditorAssetManager.h b/StarEngine/src/StarEngine/Asset/EditorAssetManager.h index 756ecbe..413ac41 100644 --- a/StarEngine/src/StarEngine/Asset/EditorAssetManager.h +++ b/StarEngine/src/StarEngine/Asset/EditorAssetManager.h @@ -17,7 +17,14 @@ namespace StarEngine { virtual bool IsAssetHandleValid(AssetHandle handle) const override; virtual bool IsAssetLoaded(AssetHandle handle) const override; + void ImportAsset(const std::filesystem::path& filepath); + const AssetMetadata& GetMetadata(AssetHandle handle) const; + + const AssetRegistry& GetAssetRegistry() const { return m_AssetRegistry; } + + void SerializeAssetRegistry(); + bool DeserializeAssetRegistry(); private: AssetRegistry m_AssetRegistry; AssetMap m_LoadedAssets; diff --git a/StarEngine/src/StarEngine/Asset/TextureImporter.cpp b/StarEngine/src/StarEngine/Asset/TextureImporter.cpp index e28638d..bc186ec 100644 --- a/StarEngine/src/StarEngine/Asset/TextureImporter.cpp +++ b/StarEngine/src/StarEngine/Asset/TextureImporter.cpp @@ -1,6 +1,8 @@ #include "sepch.h" #include "TextureImporter.h" +#include "StarEngine/Project/Project.h" + #include namespace StarEngine { @@ -9,19 +11,26 @@ namespace StarEngine { { SE_PROFILE_FUNCTION(); + return LoadTexture2D(Project::GetAssetDirectory() / metadata.FilePath); + } + + Ref TextureImporter::LoadTexture2D(const std::filesystem::path& path) + { + SE_PROFILE_FUNCTION(); + int width, height, channels; stbi_set_flip_vertically_on_load(1); Buffer data; { SE_PROFILE_SCOPE("stbi_load - TextureImporter::ImportTexture2D"); - std::string pathStr = metadata.FilePath.string(); + std::string pathStr = path.string(); data.Data = stbi_load(pathStr.c_str(), &width, &height, &channels, 0); } if (data.Data == nullptr) { - SE_CORE_ERROR("TextureImporter::ImportTexture2D - Could not load texture from filepath: {}", metadata.FilePath.string()); + SE_CORE_ERROR("TextureImporter::ImportTexture2D - Could not load texture from filepath: {}", path.string()); return nullptr; } @@ -45,6 +54,4 @@ namespace StarEngine { data.Release(); return texture; } - - } diff --git a/StarEngine/src/StarEngine/Asset/TextureImporter.h b/StarEngine/src/StarEngine/Asset/TextureImporter.h index 3d345f3..82f5099 100644 --- a/StarEngine/src/StarEngine/Asset/TextureImporter.h +++ b/StarEngine/src/StarEngine/Asset/TextureImporter.h @@ -10,6 +10,11 @@ namespace StarEngine { class TextureImporter { public: + // AssetMetadata filepath is relative to project asset directory static Ref ImportTexture2D(AssetHandle handle, const AssetMetadata& metadata); + + // Reads file directly from filesystem + // (i.e. path has to be relative / absolute to working directory) + static Ref LoadTexture2D(const std::filesystem::path& path); }; } diff --git a/StarEngine/src/StarEngine/Core/Assert.h b/StarEngine/src/StarEngine/Core/Assert.h index 28b8faf..b6bceb6 100644 --- a/StarEngine/src/StarEngine/Core/Assert.h +++ b/StarEngine/src/StarEngine/Core/Assert.h @@ -2,7 +2,6 @@ #include "StarEngine/Core/Base.h" #include "StarEngine/Core/Log.h" - #include #ifdef SE_ENABLE_ASSERTS @@ -23,3 +22,22 @@ #define SE_ASSERT(...) #define SE_CORE_ASSERT(...) #endif + +#ifdef SE_ENABLE_VERIFY + +// Alteratively we could use the same "default" message for both "WITH_MSG" and "NO_MSG" and +// provide support for custom formatting by concatenating the formatting string instead of having the format inside the default message +#define SE_INTERNAL_VERIFY_IMPL(type, check, msg, ...) { if(!(check)) { SE##type##ERROR(msg, __VA_ARGS__); SE_DEBUGBREAK(); } } +#define SE_INTERNAL_VERIFY_WITH_MSG(type, check, ...) SE_INTERNAL_VERIFY_IMPL(type, check, "Assertion failed: {0}", __VA_ARGS__) +#define SE_INTERNAL_VERIFY_NO_MSG(type, check) SE_INTERNAL_VERIFY_IMPL(type, check, "Assertion '{0}' failed at {1}:{2}", SE_STRINGIFY_MACRO(check), std::filesystem::path(__FILE__).filename().string(), __LINE__) + +#define SE_INTERNAL_VERIFY_GET_MACRO_NAME(arg1, arg2, macro, ...) macro +#define SE_INTERNAL_VERIFY_GET_MACRO(...) SE_EXPAND_MACRO( SE_INTERNAL_VERIFY_GET_MACRO_NAME(__VA_ARGS__, SE_INTERNAL_VERIFY_WITH_MSG, SE_INTERNAL_VERIFY_NO_MSG) ) + +// Currently accepts at least the condition and one additional parameter (the message) being optional +#define SE_VERIFY(...) SE_EXPAND_MACRO( SE_INTERNAL_VERIFY_GET_MACRO(__VA_ARGS__)(_, __VA_ARGS__) ) +#define SE_CORE_VERIFY(...) SE_EXPAND_MACRO( SE_INTERNAL_VERIFY_GET_MACRO(__VA_ARGS__)(_CORE_, __VA_ARGS__) ) +#else +#define SE_VERIFY(...) +#define SE_CORE_VERIFY(...) +#endif diff --git a/StarEngine/src/StarEngine/Core/Base.h b/StarEngine/src/StarEngine/Core/Base.h index ed57ec3..f47f247 100644 --- a/StarEngine/src/StarEngine/Core/Base.h +++ b/StarEngine/src/StarEngine/Core/Base.h @@ -1,11 +1,9 @@ #pragma once -#include - #include "StarEngine/Core/PlatformDetection.h" +#include -#ifdef SE_DEBUG #if defined(SE_PLATFORM_WINDOWS) #define SE_DEBUGBREAK() __debugbreak() #elif defined(SE_PLATFORM_LINUX) @@ -14,9 +12,13 @@ #else #error "Platform doesn't support debugbreak yet!" #endif + +#ifdef SE_DEBUG #define SE_ENABLE_ASSERTS -#else -#define SE_DEBUGBREAK() +#endif + +#ifndef SE_DIST +#define SE_ENABLE_VERIFY #endif #define SE_EXPAND_MACRO(x) x @@ -46,6 +48,5 @@ namespace StarEngine { } - #include "StarEngine/Core/Log.h" #include "StarEngine/Core/Assert.h" diff --git a/StarEngine/src/StarEngine/Project/Project.cpp b/StarEngine/src/StarEngine/Project/Project.cpp index 8334dee..8686fae 100644 --- a/StarEngine/src/StarEngine/Project/Project.cpp +++ b/StarEngine/src/StarEngine/Project/Project.cpp @@ -20,6 +20,9 @@ namespace StarEngine { { project->m_ProjectDirectory = path.parent_path(); s_ActiveProject = project; + std::shared_ptr editorAssetManager = std::make_shared(); + s_ActiveProject->m_AssetManager = editorAssetManager; + editorAssetManager->DeserializeAssetRegistry(); return s_ActiveProject; } diff --git a/StarEngine/src/StarEngine/Project/Project.h b/StarEngine/src/StarEngine/Project/Project.h index 826adae..e3c353d 100644 --- a/StarEngine/src/StarEngine/Project/Project.h +++ b/StarEngine/src/StarEngine/Project/Project.h @@ -17,6 +17,7 @@ namespace StarEngine { std::filesystem::path StartScene; std::filesystem::path AssetDirectory; + std::filesystem::path AssetRegistryPath; // Relative to AssetDirectory std::filesystem::path ScriptModulePath; }; @@ -35,6 +36,12 @@ namespace StarEngine { return GetProjectDirectory() / s_ActiveProject->m_Config.AssetDirectory; } + static std::filesystem::path GetAssetRegistryPath() + { + SE_CORE_ASSERT(s_ActiveProject); + return GetAssetDirectory() / s_ActiveProject->m_Config.AssetRegistryPath; + } + // TODO: move to asset manager when we have one static std::filesystem::path GetAssetFileSystemPath(const std::filesystem::path& path) { diff --git a/StarEngine/src/StarEngine/Project/ProjectSerializer.cpp b/StarEngine/src/StarEngine/Project/ProjectSerializer.cpp index 64a597c..9b61380 100644 --- a/StarEngine/src/StarEngine/Project/ProjectSerializer.cpp +++ b/StarEngine/src/StarEngine/Project/ProjectSerializer.cpp @@ -4,16 +4,6 @@ #include #include -namespace fmt { - template <> - struct formatter : formatter { - template - auto format(const std::filesystem::path& path, FormatContext& ctx) const { - return formatter::format(path.string(), ctx); - } - }; -} // namespace fmt - namespace StarEngine { ProjectSerializer::ProjectSerializer(Ref project) @@ -34,6 +24,7 @@ namespace StarEngine { out << YAML::Key << "Name" << YAML::Value << config.Name; out << YAML::Key << "StartScene" << YAML::Value << config.StartScene.string(); out << YAML::Key << "AssetDirectory" << YAML::Value << config.AssetDirectory.string(); + out << YAML::Key << "AssetRegistryPath" << YAML::Value << config.AssetRegistryPath.string(); out << YAML::Key << "ScriptModulePath" << YAML::Value << config.ScriptModulePath.string(); out << YAML::EndMap; // Project } @@ -57,7 +48,8 @@ namespace StarEngine { } catch (YAML::ParserException e) { - SE_CORE_ERROR("Failed to load project file '{0}'\n {1}", filepath, e.what()); + SE_CORE_ERROR("Failed to load project file '{0}'\n {1}", filepath.string(), e.what()); + return false; } @@ -68,6 +60,8 @@ namespace StarEngine { config.Name = projectNode["Name"].as(); config.StartScene = projectNode["StartScene"].as(); config.AssetDirectory = projectNode["AssetDirectory"].as(); + if (projectNode["AssetRegistryPath"]) + config.AssetRegistryPath = projectNode["AssetRegistryPath"].as(); config.ScriptModulePath = projectNode["ScriptModulePath"].as(); return true; } diff --git a/StarEngine/src/StarEngine/Project/ProjectSerializer.h b/StarEngine/src/StarEngine/Project/ProjectSerializer.h index 093e875..88d89c9 100644 --- a/StarEngine/src/StarEngine/Project/ProjectSerializer.h +++ b/StarEngine/src/StarEngine/Project/ProjectSerializer.h @@ -2,8 +2,8 @@ #include "Project.h" -namespace StarEngine -{ +namespace StarEngine { + class ProjectSerializer { public: diff --git a/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp b/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp index 1ca24f7..3ac0d84 100644 --- a/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp +++ b/StarEngine/src/StarEngine/Renderer/Renderer2D.cpp @@ -5,6 +5,8 @@ #include "StarEngine/Renderer/UniformBuffer.h" #include "StarEngine/Renderer/RenderCommand.h" +#include "StarEngine/Asset/AssetManager.h" + #include #include @@ -404,6 +406,7 @@ namespace StarEngine { void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref& texture, float tilingFactor, const glm::vec4& tintColor, int entityID) { SE_PROFILE_FUNCTION(); + SE_CORE_VERIFY(texture); constexpr size_t quadVertexCount = 4; constexpr glm::vec2 textureCoords[] = { { 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f } }; @@ -549,7 +552,8 @@ namespace StarEngine { { if (src.Texture) { - DrawQuad(transform, src.Texture, src.TilingFactor, src.Color, entityID); + Ref texture = AssetManager::GetAsset(src.Texture); + DrawQuad(transform, texture, src.TilingFactor, src.Color, entityID); } else { diff --git a/StarEngine/src/StarEngine/Scene/Components.h b/StarEngine/src/StarEngine/Scene/Components.h index 738382b..f981c8c 100644 --- a/StarEngine/src/StarEngine/Scene/Components.h +++ b/StarEngine/src/StarEngine/Scene/Components.h @@ -58,7 +58,7 @@ namespace StarEngine { struct SpriteRendererComponent { glm::vec4 Color{ 1.0f, 1.0f, 1.0f, 1.0f }; - Ref Texture; + AssetHandle Texture = 0; float TilingFactor = 1.0f; SpriteRendererComponent() = default; diff --git a/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp b/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp index 90b0331..0ab5182 100644 --- a/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp +++ b/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp @@ -293,8 +293,7 @@ namespace StarEngine { auto& spriteRendererComponent = entity.GetComponent(); out << YAML::Key << "Color" << YAML::Value << spriteRendererComponent.Color; - if (spriteRendererComponent.Texture) - out << YAML::Key << "TexturePath" << YAML::Value << spriteRendererComponent.Texture->GetPath(); + out << YAML::Key << "TextureHandle" << YAML::Value << spriteRendererComponent.Texture; out << YAML::Key << "TilingFactor" << YAML::Value << spriteRendererComponent.TilingFactor; @@ -535,11 +534,15 @@ namespace StarEngine { if (spriteRendererComponent["TexturePath"]) { - std::string texturePath = spriteRendererComponent["TexturePath"].as(); - auto path = Project::GetAssetFileSystemPath(texturePath); - src.Texture = Texture2D::Create(path.string()); + // NOTE: legacy, could try and find something in the asset registry that matches? + // std::string texturePath = spriteRendererComponent["TexturePath"].as(); + // auto path = Project::GetAssetFileSystemPath(texturePath); + // src.Texture = Texture2D::Create(path.string()); } + if (spriteRendererComponent["TextureHandle"]) + src.Texture = spriteRendererComponent["TextureHandle"].as(); + if (spriteRendererComponent["TilingFactor"]) src.TilingFactor = spriteRendererComponent["TilingFactor"].as(); } diff --git a/StarEngine/vendor/mono/lib/Dist/libmono-static-sgen.lib b/StarEngine/vendor/mono/lib/Dist/libmono-static-sgen.lib new file mode 100644 index 0000000000000000000000000000000000000000..346a117d3bde3d1b2dda7cedc071a5a6669b327f GIT binary patch literal 33872520 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%0A7}4eZ&Lvsc7Uk-(FL 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%0D;+w+; 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

1sznhOp6U3XU}+1bEUe;Av{qI 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

5S@la;Wza%63)H3X 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