From 875a77ff5b22128138ddb73806da55053b29bd13 Mon Sep 17 00:00:00 2001 From: Atdunbg <979541498@qq.com> Date: Tue, 28 Oct 2025 13:48:36 +0800 Subject: [PATCH] add project work --- Editor/src/Editor/EditorLayer.cpp | 82 +++++++++++++++---- Editor/src/Editor/EditorLayer.h | 8 +- .../src/Editor/Panels/ContentBroswerPanel.cpp | 10 +-- .../src/Editor/Panels/ContentBroswerPanel.h | 1 + .../src/Editor/Panels/SceneHierachyPanel.cpp | 21 ++--- .../Sources/Hazel/InternalCalls.cs | 10 +++ .../Sources/Hazel/Scene/Components.cs | 17 ++++ Hazel-ScriptCore/Sources/Hazel/Vector.cs | 11 +++ Hazel/src/Hazel/Core/Application.cpp | 1 - Hazel/src/Hazel/ImGui/ImGuiLayer.cpp | 6 ++ Hazel/src/Hazel/ImGui/ImGuiLayer.h | 2 + Hazel/src/Hazel/Physics/Physics2D.h | 41 ++++++++++ Hazel/src/Hazel/Project/Project.cpp | 45 ++++++++++ Hazel/src/Hazel/Project/Project.h | 65 +++++++++++++++ Hazel/src/Hazel/Project/ProjectSerializer.cpp | 71 ++++++++++++++++ Hazel/src/Hazel/Project/ProjectSerializer.h | 30 +++++++ Hazel/src/Hazel/Scene/Scene.cpp | 46 ++--------- Hazel/src/Hazel/Scene/Scene.h | 4 +- Hazel/src/Hazel/Scene/SceneSerializer.cpp | 8 +- Hazel/src/Hazel/Scripting/ScriptEngine.cpp | 15 +++- Hazel/src/Hazel/Scripting/ScriptGlue.cpp | 41 ++++++++++ Hazel/src/Hazel/UI/UI.h | 43 ++++++++++ 22 files changed, 498 insertions(+), 80 deletions(-) create mode 100644 Hazel/src/Hazel/Physics/Physics2D.h create mode 100644 Hazel/src/Hazel/Project/Project.cpp create mode 100644 Hazel/src/Hazel/Project/Project.h create mode 100644 Hazel/src/Hazel/Project/ProjectSerializer.cpp create mode 100644 Hazel/src/Hazel/Project/ProjectSerializer.h create mode 100644 Hazel/src/Hazel/UI/UI.h diff --git a/Editor/src/Editor/EditorLayer.cpp b/Editor/src/Editor/EditorLayer.cpp index 6aa58e0..9e65cd1 100644 --- a/Editor/src/Editor/EditorLayer.cpp +++ b/Editor/src/Editor/EditorLayer.cpp @@ -14,14 +14,13 @@ #include #include "imgui_internal.h" +#include "Hazel/Project/Project.h" #include "Hazel/Scripting/ScriptEngine.h" namespace Hazel { - extern const std::filesystem::path g_AssetPath; - EditorLayer::EditorLayer() : Layer("HazelEditor"), m_CameraController((float)Application::Get().GetWindow().GetWidth() / (float)Application::Get().GetWindow().GetHeight()) { @@ -61,10 +60,12 @@ namespace Hazel auto commandLineArgs = Application::Get().GetSpecification().commandLineArgs; if (commandLineArgs.count > 1) { - auto scenePath = commandLineArgs.args[1]; - SceneSerializer sceneSerializer(m_ActiveScene); - - sceneSerializer.Deserialize(scenePath); + auto projectFilePath = commandLineArgs.args[1]; + OpenProject(projectFilePath); + }else + { + if (!OpenProject()) + Application::Get().Close(); } } @@ -275,11 +276,13 @@ namespace Hazel // ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen); // ImGui::MenuItem("Padding", NULL, &opt_padding); // ImGui::Separator(); - if (ImGui::MenuItem("New", "Ctrl+N")) - NewScene(); - if (ImGui::MenuItem("Open...", "Ctrl+O")) - OpenScene(); - if (ImGui::MenuItem("Save", "Ctrl+S", false, m_ActiveScene ? true : false)) + if (ImGui::MenuItem("Open Project", "Ctrl+O")) + OpenProject(); + ImGui::Separator(); + + if (ImGui::MenuItem("New Scene", "Ctrl+N")) + NewScene(); + if (ImGui::MenuItem("Save", "Ctrl+S", false, m_ActiveScene ? true : false)) SaveScene(); if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S")) SaveSceneAs(); @@ -305,7 +308,7 @@ namespace Hazel // Scene Hierachy Panel m_SceneHierachyPanel.OnImGuiRender(); - m_ContentBroswerPanel.OnImGuiRender(); + m_ContentBroswerPanel->OnImGuiRender(); // Render Status { @@ -391,7 +394,7 @@ namespace Hazel if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROSWER_ITEM")) { const wchar_t* path = (const wchar_t*)payload->Data; - OpenScene(std::filesystem::path(g_AssetPath) / path); + OpenScene(path); } ImGui::EndDragDropTarget(); } @@ -543,6 +546,37 @@ namespace Hazel } } + void EditorLayer::NewProject() + { + Project::New(); + } + + bool EditorLayer::OpenProject() + { + std::string path = FileDiaglogs::OpenFile("Hazel Project (*.proj)\0*.proj\0"); + if (path.empty()) + return false; + + OpenProject(path); + return true; + } + + void EditorLayer::OpenProject(const std::filesystem::path& projectPath) + { + if (Project::Load(projectPath)) + { + ScriptEngine::Init(); + auto startScenePath = Project::GetAssetsFileSystemPath(Project::GetActive()->GetConfig().StartScene); + OpenScene(startScenePath); + m_ContentBroswerPanel = CreateScope(); + } + } + + void EditorLayer::SaveProject() const + { + + } + void EditorLayer::SerializeScene(Ref scene, const std::filesystem::path& scenePath) const { const SceneSerializer serializer(scene); @@ -555,7 +589,12 @@ namespace Hazel return; Entity selectedEntity = m_SceneHierachyPanel.GetSelectedEntity(); if (selectedEntity) - m_EditorScene->DuplicateEntity(selectedEntity); + { + Entity newEntity = m_EditorScene->DuplicateEntity(selectedEntity); + m_SceneHierachyPanel.SetSelectedEntity(newEntity); + } + + } void EditorLayer::OnScenePlay() @@ -649,7 +688,7 @@ namespace Hazel else if (Input::IsKeyPressed(KeyCode::S)) SaveScene(); else if (Input::IsKeyPressed(KeyCode::O)) - OpenScene(); + OpenProject(); else if (Input::IsKeyPressed(KeyCode::N)) NewScene(); else if (Input::IsKeyPressed(KeyCode::D)) @@ -668,6 +707,19 @@ namespace Hazel else if (Input::IsKeyPressed(KeyCode::R)) ChangeOptMode(ImGuizmo::OPERATION::ROTATE); } + + if (Input::IsKeyPressed(KeyCode::DELETE)) + { + if (Application::Get().GetImGuiLayer()->GetActiveWidgetID() == 0) + { + Entity selectedEntity = m_SceneHierachyPanel.GetSelectedEntity(); + if (selectedEntity) + { + m_SceneHierachyPanel.SetSelectedEntity({}); + m_ActiveScene->DestroyEntity(selectedEntity); + } + } + } } } diff --git a/Editor/src/Editor/EditorLayer.h b/Editor/src/Editor/EditorLayer.h index 0380c18..61ec133 100644 --- a/Editor/src/Editor/EditorLayer.h +++ b/Editor/src/Editor/EditorLayer.h @@ -38,6 +38,11 @@ namespace Hazel void NewScene(); void SaveScene() const; + void NewProject(); + bool OpenProject(); + void OpenProject(const std::filesystem::path& projectPath); + void SaveProject() const; + void SerializeScene(Ref scene, const std::filesystem::path& scenePath) const; void OnDuplicateEntity(); @@ -70,8 +75,9 @@ namespace Hazel Ref m_FrameBuffer; Ref m_RuntimeFrameBuffer; + // Panels SceneHierachyPanel m_SceneHierachyPanel; - ContentBroswerPanel m_ContentBroswerPanel; + Scope m_ContentBroswerPanel; int m_GizmoType = -1; int m_GizmoMode = -1; diff --git a/Editor/src/Editor/Panels/ContentBroswerPanel.cpp b/Editor/src/Editor/Panels/ContentBroswerPanel.cpp index fdee4a5..72084aa 100644 --- a/Editor/src/Editor/Panels/ContentBroswerPanel.cpp +++ b/Editor/src/Editor/Panels/ContentBroswerPanel.cpp @@ -8,13 +8,13 @@ #include <../../../../Hazel/vendor/imgui/imgui.h> #include +#include "Hazel/Project/Project.h" + namespace Hazel { - extern const std::filesystem::path g_AssetPath = "assets"; - ContentBroswerPanel::ContentBroswerPanel() - : m_CurrentDirectory(g_AssetPath) + : m_BaseDirectory(Project::GetAssetsDirectory()), m_CurrentDirectory(m_BaseDirectory) { m_DirectoryIcon = Texture2D::Create("Resources/Icons/ContentBrowser/DirectoryIcon.png"); m_FileIcon = Texture2D::Create("Resources/Icons/ContentBrowser/FileIcon.png"); @@ -28,7 +28,7 @@ namespace Hazel ImGui::Text("%s", m_CurrentDirectory.string().c_str()); ImGui::Separator(); - if (m_CurrentDirectory != std::filesystem::path(g_AssetPath)) + if (m_CurrentDirectory != std::filesystem::path(m_BaseDirectory)) { if (ImGui::Button("..")) { @@ -60,7 +60,7 @@ namespace Hazel if (ImGui::BeginDragDropSource()) { - auto relativePath = std::filesystem::relative(path, g_AssetPath); + auto relativePath = std::filesystem::relative(path); const wchar_t* itemPath = relativePath.c_str(); ImGui::SetDragDropPayload("CONTENT_BROSWER_ITEM", itemPath, (wcslen(itemPath) + 1) * sizeof(wchar_t), ImGuiCond_Once); diff --git a/Editor/src/Editor/Panels/ContentBroswerPanel.h b/Editor/src/Editor/Panels/ContentBroswerPanel.h index 3a5df1c..105c404 100644 --- a/Editor/src/Editor/Panels/ContentBroswerPanel.h +++ b/Editor/src/Editor/Panels/ContentBroswerPanel.h @@ -19,6 +19,7 @@ namespace Hazel void OnImGuiRender(); private: + std::filesystem::path m_BaseDirectory; std::filesystem::path m_CurrentDirectory; Ref m_DirectoryIcon; diff --git a/Editor/src/Editor/Panels/SceneHierachyPanel.cpp b/Editor/src/Editor/Panels/SceneHierachyPanel.cpp index f794850..c03a1fa 100644 --- a/Editor/src/Editor/Panels/SceneHierachyPanel.cpp +++ b/Editor/src/Editor/Panels/SceneHierachyPanel.cpp @@ -9,13 +9,12 @@ #include #include #include +#include "Hazel/UI/UI.h" #include "Hazel/Scripting/ScriptEngine.h" namespace Hazel { - extern const std::filesystem::path g_AssetPath; - SceneHierachyPanel::SceneHierachyPanel(const Ref& context) { SetContext(context); @@ -99,7 +98,7 @@ namespace Hazel if (entityDeleted) { - m_Context->DestoryEntity(entity); + m_Context->DestroyEntity(entity); if (m_SelectionContext == entity) { m_SelectionContext = {}; @@ -365,21 +364,15 @@ namespace Hazel DrawComponent("Script", entity, [entity, &scene = m_Context](auto& component) mutable { bool scriptClassExists = ScriptEngine::ClassExists(component.ClassName); - bool setStyleFlag = false; static char buffer[64] = {}; strcpy_s(buffer, sizeof(buffer), component.ClassName.c_str()); - if (!scriptClassExists) - { - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.9f, 0.2f, 0.3f, 1.0f)); - setStyleFlag = true; - } - + UI::ScopedStyleColor textColor(ImGuiCol_Text, ImVec4(0.9f, 0.2f, 0.3f, 1.0f), !scriptClassExists); if (ImGui::InputText("Class", buffer, sizeof(buffer))) { component.ClassName = buffer; - scriptClassExists = ScriptEngine::ClassExists(component.ClassName); + return; } @@ -447,10 +440,6 @@ namespace Hazel } } - - if (setStyleFlag) - ImGui::PopStyleColor(); - }); DrawComponent("Sprite Renderer", entity, [](auto& component) @@ -471,7 +460,7 @@ namespace Hazel if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROSWER_ITEM")) { const wchar_t* path = (const wchar_t*)payload->Data; - std::filesystem::path texturePath = std::filesystem::path(g_AssetPath) / path; + const std::filesystem::path texturePath(path); component.Texture = Texture2D::Create(texturePath.string()); } ImGui::EndDragDropTarget(); diff --git a/Hazel-ScriptCore/Sources/Hazel/InternalCalls.cs b/Hazel-ScriptCore/Sources/Hazel/InternalCalls.cs index a02799d..b82bfbd 100644 --- a/Hazel-ScriptCore/Sources/Hazel/InternalCalls.cs +++ b/Hazel-ScriptCore/Sources/Hazel/InternalCalls.cs @@ -32,6 +32,16 @@ namespace Hazel [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static void RigidBody2DComponent_ApplyLinearImpulseToCenter(ulong entityID, ref Vector2 impulse, bool wake); + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal extern static void RigidBody2DComponent_GetLinearVelocity(ulong entityID, out Vector2 LinearVelocity); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal extern static RigidBody2DComponent.BodyType RigidBody2DComponent_GetType(ulong entityID); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal extern static void RigidBody2DComponent_SetType(ulong entityID, RigidBody2DComponent.BodyType bodyType); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static bool Input_IsKeyDown(KeyCode keycode); } diff --git a/Hazel-ScriptCore/Sources/Hazel/Scene/Components.cs b/Hazel-ScriptCore/Sources/Hazel/Scene/Components.cs index c5dc429..d7fef1d 100644 --- a/Hazel-ScriptCore/Sources/Hazel/Scene/Components.cs +++ b/Hazel-ScriptCore/Sources/Hazel/Scene/Components.cs @@ -21,6 +21,23 @@ namespace Hazel public class RigidBody2DComponent : Component { + public enum BodyType { Static = 0, Dynamic, Kinematic} + + public Vector2 LinearVelocity + { + get + { + InternalCalls.RigidBody2DComponent_GetLinearVelocity(Entity.ID, out Vector2 velocity); + return velocity; + } + } + + public BodyType Type + { + get => InternalCalls.RigidBody2DComponent_GetType(Entity.ID); + set => InternalCalls.RigidBody2DComponent_SetType(Entity.ID, value); + } + public void ApplyLinearImpulse(Vector2 impulse, Vector2 point, bool wake) { InternalCalls.RigidBody2DComponent_ApplyLinearImpulse(Entity.ID, ref impulse, ref point, wake); } diff --git a/Hazel-ScriptCore/Sources/Hazel/Vector.cs b/Hazel-ScriptCore/Sources/Hazel/Vector.cs index 8e8b112..4e38588 100644 --- a/Hazel-ScriptCore/Sources/Hazel/Vector.cs +++ b/Hazel-ScriptCore/Sources/Hazel/Vector.cs @@ -1,3 +1,4 @@ +using System; namespace Hazel { @@ -26,6 +27,16 @@ namespace Hazel { return new Vector2(a.X + b.X, a.Y + b.Y); } + + public float LengthSquared() + { + return X * X + Y * Y; + } + + public float Length() + { + return (float)Math.Sqrt(LengthSquared()); + } } public struct Vector3 diff --git a/Hazel/src/Hazel/Core/Application.cpp b/Hazel/src/Hazel/Core/Application.cpp index 52a5b60..c3a5074 100644 --- a/Hazel/src/Hazel/Core/Application.cpp +++ b/Hazel/src/Hazel/Core/Application.cpp @@ -32,7 +32,6 @@ namespace Hazel { m_Window->SetWindowResizeEventCallback(std::bind(&Application::OnWindowResize, this, std::placeholders::_1)); Renderer::Init(); - ScriptEngine::Init(); m_imguiLayer = new ImGuiLayer(); PushOverlay(m_imguiLayer); diff --git a/Hazel/src/Hazel/ImGui/ImGuiLayer.cpp b/Hazel/src/Hazel/ImGui/ImGuiLayer.cpp index d638a62..2686fe8 100644 --- a/Hazel/src/Hazel/ImGui/ImGuiLayer.cpp +++ b/Hazel/src/Hazel/ImGui/ImGuiLayer.cpp @@ -10,6 +10,7 @@ #include #include #include "ImGuizmo.h" +#include "imgui_internal.h" namespace Hazel { @@ -111,6 +112,11 @@ namespace Hazel } } + uint32_t ImGuiLayer::GetActiveWidgetID() const + { + return GImGui->ActiveId; + } + void ImGuiLayer::SetDarkThemeColors() { auto& colors = ImGui::GetStyle().Colors; diff --git a/Hazel/src/Hazel/ImGui/ImGuiLayer.h b/Hazel/src/Hazel/ImGui/ImGuiLayer.h index 52f3fa9..422881a 100644 --- a/Hazel/src/Hazel/ImGui/ImGuiLayer.h +++ b/Hazel/src/Hazel/ImGui/ImGuiLayer.h @@ -24,6 +24,8 @@ namespace Hazel { void BlockEvents(const bool block) {m_BlockEvent = block;} + uint32_t GetActiveWidgetID() const; + private: void SetDarkThemeColors(); diff --git a/Hazel/src/Hazel/Physics/Physics2D.h b/Hazel/src/Hazel/Physics/Physics2D.h new file mode 100644 index 0000000..55ff8e8 --- /dev/null +++ b/Hazel/src/Hazel/Physics/Physics2D.h @@ -0,0 +1,41 @@ +// +// Created by sfd on 25-10-27. +// + +#ifndef PHYSICS2D_H +#define PHYSICS2D_H +#include "box2d/types.h" +#include "Hazel/Core/Log.h" +#include "Hazel/Scene/Components.h" + +namespace Hazel::Utils +{ + + inline b2BodyType RigidBodyTypeToBox2DBodyType(const RigidBody2DComponent::BodyType type) + { + switch (type) + { + case RigidBody2DComponent::BodyType::Static: return b2_staticBody; + case RigidBody2DComponent::BodyType::Dynamic: return b2_dynamicBody; + case RigidBody2DComponent::BodyType::Kinematic: return b2_kinematicBody; + } + + HZ_CORE_ERROR("Unknown body type"); + return b2_staticBody; + } + + inline RigidBody2DComponent::BodyType Rigidbody2DTypeFromBox2DBody(const b2BodyType bodyType) + { + switch (bodyType) + { + case b2_staticBody: return RigidBody2DComponent::BodyType::Static; + case b2_dynamicBody: return RigidBody2DComponent::BodyType::Dynamic; + case b2_kinematicBody: return RigidBody2DComponent::BodyType::Kinematic; + } + + HZ_CORE_ASSERT(false, "Unknown body type"); + return RigidBody2DComponent::BodyType::Static; + } +} + +#endif //PHYSICS2D_H diff --git a/Hazel/src/Hazel/Project/Project.cpp b/Hazel/src/Hazel/Project/Project.cpp new file mode 100644 index 0000000..f4192a2 --- /dev/null +++ b/Hazel/src/Hazel/Project/Project.cpp @@ -0,0 +1,45 @@ +// +// Created by sfd on 25-10-27. +// + +#include "Project.h" + +#include "ProjectSerializer.h" + +namespace Hazel +{ + Ref Project::New() + { + s_ActiveProject = CreateRef(); + + return s_ActiveProject; + } + + Ref Project::Load(const std::filesystem::path& path) + { + Ref project = CreateRef(); + + ProjectSerializer serializer(project); + + if (serializer.Deserialize(path)) + { + project->m_ProjectDirectory = path; + s_ActiveProject = project; + return project; + } + + return nullptr; + } + + bool Project::SaveActive(const std::filesystem::path& path) + { + ProjectSerializer serializer(s_ActiveProject); + if (serializer.Serialize(path)) + { + s_ActiveProject->m_ProjectDirectory = path.parent_path(); + return true; + } + + return false; + } +} diff --git a/Hazel/src/Hazel/Project/Project.h b/Hazel/src/Hazel/Project/Project.h new file mode 100644 index 0000000..4615176 --- /dev/null +++ b/Hazel/src/Hazel/Project/Project.h @@ -0,0 +1,65 @@ +// +// Created by sfd on 25-10-27. +// + +#ifndef PROJECT_H +#define PROJECT_H +#include +#include + +#include "Hazel/Core/assert.h" +#include "Hazel/Core/Core.h" + + +namespace Hazel +{ + struct ProjectConfig + { + std::string Name = "Untitled"; + std::filesystem::path StartScene; + + std::filesystem::path AssetsDirectory; + std::filesystem::path ScriptModulePath; + }; + + class HAZEL_API Project { + public: + static const std::filesystem::path& GetProjectDirectory() + { + HZ_CORE_ASSERT(s_ActiveProject); + return s_ActiveProject->m_ProjectDirectory; + } + + static std::filesystem::path GetAssetsDirectory() + { + HZ_CORE_ASSERT(s_ActiveProject); + return GetProjectDirectory() / s_ActiveProject->m_Config.AssetsDirectory; + } + + static std::filesystem::path GetAssetsFileSystemPath(const std::filesystem::path& path) + { + HZ_CORE_ASSERT(s_ActiveProject); + return GetAssetsDirectory() / path; + } + + + ProjectConfig& GetConfig() { return m_Config; } + + static Ref GetActive() { return s_ActiveProject; } + + static Ref New(); + static Ref Load(const std::filesystem::path& path); + + static bool SaveActive(const std::filesystem::path& path); + private: + ProjectConfig m_Config; + std::filesystem::path m_ProjectDirectory; + + inline static Ref s_ActiveProject; + + }; + +} + + +#endif //PROJECT_H diff --git a/Hazel/src/Hazel/Project/ProjectSerializer.cpp b/Hazel/src/Hazel/Project/ProjectSerializer.cpp new file mode 100644 index 0000000..1c0069c --- /dev/null +++ b/Hazel/src/Hazel/Project/ProjectSerializer.cpp @@ -0,0 +1,71 @@ +// +// Created by sfd on 25-10-27. +// + +#include "ProjectSerializer.h" + +#include + +#include "Project.h" +#include "yaml-cpp/yaml.h" + +namespace Hazel +{ + ProjectSerializer::ProjectSerializer(const Ref& project) + : m_Project(project) + { + } + bool ProjectSerializer::Serialize(const std::filesystem::path& path) const + { + const auto& config = m_Project->GetConfig(); + + YAML::Emitter out; + + { + out << YAML::BeginMap; // Root + out << YAML::Key << "Project" << YAML::Value; + + { + out << YAML::BeginMap; // Project + out << YAML::Key << "Name" << YAML::Value << config.Name; + out << YAML::Key << "StartScene" << YAML::Value << config.StartScene.string(); + out << YAML::Key << "AssetsDirectory" << YAML::Value << config.AssetsDirectory.string(); + out << YAML::Key << "ScriptModulePath" << YAML::Value << config.ScriptModulePath.string(); + out << YAML::EndMap; + } + } + + std::ofstream fout(path); + fout << out.c_str(); + + return true; + } + + bool ProjectSerializer::Deserialize(const std::filesystem::path& path) const + { + auto& config = m_Project->GetConfig(); + + YAML::Node data; + + try + { + data = YAML::LoadFile(path.string()); + }catch (YAML::Exception& e) + { + HZ_CORE_ERROR("failed to load project file: {0}\n {1}", path.string(),e.what()); + return false; + } + + auto projectNode = data["Project"]; + if (!projectNode) + return false; + + config.Name = projectNode["Name"].as(); + config.StartScene = projectNode["StartScene"].as(); + config.AssetsDirectory = projectNode["AssetsDirectory"].as(); + config.ScriptModulePath = projectNode["ScriptModulePath"].as(); + return true; + + + } +} diff --git a/Hazel/src/Hazel/Project/ProjectSerializer.h b/Hazel/src/Hazel/Project/ProjectSerializer.h new file mode 100644 index 0000000..3851f19 --- /dev/null +++ b/Hazel/src/Hazel/Project/ProjectSerializer.h @@ -0,0 +1,30 @@ +// +// Created by sfd on 25-10-27. +// + +#ifndef PROJECTSERIALIZER_H +#define PROJECTSERIALIZER_H + +#include + +#include "Hazel/Core/Core.h" + +namespace Hazel +{ + class Project; + + class HAZEL_API ProjectSerializer { + public: + ProjectSerializer(const Ref& project); + + bool Serialize(const std::filesystem::path& path) const; + bool Deserialize(const std::filesystem::path& path) const; + + private: + Ref m_Project; + }; +} + + + +#endif //PROJECTSERIALIZER_H diff --git a/Hazel/src/Hazel/Scene/Scene.cpp b/Hazel/src/Hazel/Scene/Scene.cpp index f1d585b..042e00d 100644 --- a/Hazel/src/Hazel/Scene/Scene.cpp +++ b/Hazel/src/Hazel/Scene/Scene.cpp @@ -15,23 +15,12 @@ #include "box2d/box2d.h" #include "box2d/id.h" #include "Hazel/Core/assert.h" +#include "Hazel/Physics/Physics2D.h" #include "Hazel/Scripting/ScriptEngine.h" namespace Hazel { - static b2BodyType RigidBodyTypeToBox2DBodyType(RigidBody2DComponent::BodyType type) - { - switch (type) - { - case RigidBody2DComponent::BodyType::Static: return b2_staticBody; - case RigidBody2DComponent::BodyType::Dynamic: return b2_dynamicBody; - case RigidBody2DComponent::BodyType::Kinematic: return b2_kinematicBody; - } - - HZ_CORE_ERROR("Unknown body type"); - return b2_staticBody; - } Scene::Scene() { @@ -105,16 +94,7 @@ namespace Hazel // Copy all components except IDComponent and TagComponent CopyComponent(AllComponents{}, dstSceneRegistry, srcSceneRegistry, enttMap); - /* - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - CopyComponent(dstSceneRegistry, srcSceneRegistry, enttMap); - */ + return newScene; } @@ -136,10 +116,10 @@ namespace Hazel return entity; } - void Scene::DestoryEntity(const Entity entity) + void Scene::DestroyEntity(Entity entity) { + m_EnttMap.erase(entity.GetUUID()); m_Registry.destroy(entity); - m_EnttMap.erase((entt::id_type)entity); } @@ -162,7 +142,7 @@ namespace Hazel auto& rb2D = entity.GetComponent(); b2BodyDef bodyDef = b2DefaultBodyDef(); - bodyDef.type = RigidBodyTypeToBox2DBodyType(rb2D.Type); + bodyDef.type = Utils::RigidBodyTypeToBox2DBodyType(rb2D.Type); bodyDef.position = {transform.Translation.x, transform.Translation.y}; float angle = transform.Rotation.z; bodyDef.rotation = b2Rot{cos(angle), sin(angle)}; @@ -443,21 +423,13 @@ namespace Hazel } } - void Scene::DuplicateEntity(Entity entity) + Entity Scene::DuplicateEntity(Entity entity) { - Entity newEntity = CreateEntity(entity.GetName() + " copy"); + Entity newEntity = CreateEntity(entity.GetName() + "_copy"); CopyComponentIfExists(AllComponents{}, newEntity, entity); - /* - CopyComponentIfExists(newEntity, entity); - CopyComponentIfExists(newEntity, entity); - CopyComponentIfExists(newEntity, entity); - CopyComponentIfExists(newEntity, entity); - CopyComponentIfExists(newEntity, entity); - CopyComponentIfExists(newEntity, entity); - CopyComponentIfExists(newEntity, entity); - CopyComponentIfExists(newEntity, entity); - */ + + return newEntity; } Entity Scene::FindEntityByName(std::string_view name) diff --git a/Hazel/src/Hazel/Scene/Scene.h b/Hazel/src/Hazel/Scene/Scene.h index 60f061b..ff47337 100644 --- a/Hazel/src/Hazel/Scene/Scene.h +++ b/Hazel/src/Hazel/Scene/Scene.h @@ -29,7 +29,7 @@ namespace Hazel Entity CreateEntity(const std::string& name = std::string()); Entity CreateEntityWithUUID(UUID uuid, const std::string& name = std::string()); - void DestoryEntity(Entity entity); + void DestroyEntity(Entity entity); void OnRuntimeStart(); void OnRuntimeStop(); @@ -42,7 +42,7 @@ namespace Hazel void OnUpdateEditor(TimeStep& ts, const EditorCamera& camera); void OnViewportResize(uint32_t width, uint32_t height); - void DuplicateEntity(Entity entity); + Entity DuplicateEntity(Entity entity); Entity FindEntityByName(std::string_view name); Entity GetPrimaryCameraEntity(); diff --git a/Hazel/src/Hazel/Scene/SceneSerializer.cpp b/Hazel/src/Hazel/Scene/SceneSerializer.cpp index 8af2579..97fbd88 100644 --- a/Hazel/src/Hazel/Scene/SceneSerializer.cpp +++ b/Hazel/src/Hazel/Scene/SceneSerializer.cpp @@ -8,6 +8,7 @@ #include "Components.h" #include "Entity.h" +#include "Hazel/Project/Project.h" #include "Hazel/Scripting/ScriptEngine.h" #include "yaml-cpp/yaml.h" @@ -541,7 +542,12 @@ namespace Hazel sprite.Color = spriteRendererComponent["Color"].as(); sprite.TilingFactor = spriteRendererComponent["TilingFactor"].as(); if (spriteRendererComponent["TexturePath"]) - sprite.Texture = Texture2D::Create(spriteRendererComponent["TexturePath"].as()); + { + std::string texturePath = spriteRendererComponent["TexturePath"].as(); + auto path = Project::GetAssetsFileSystemPath(texturePath); + sprite.Texture = Texture2D::Create(path.string()); + // sprite.Texture = Texture2D::Create(spriteRendererComponent["TexturePath"].as()); + } } auto circleRendererComponent = entity["CircleRendererComponent"]; diff --git a/Hazel/src/Hazel/Scripting/ScriptEngine.cpp b/Hazel/src/Hazel/Scripting/ScriptEngine.cpp index 29c7191..848ea17 100644 --- a/Hazel/src/Hazel/Scripting/ScriptEngine.cpp +++ b/Hazel/src/Hazel/Scripting/ScriptEngine.cpp @@ -12,6 +12,7 @@ #include "Hazel/Core/Application.h" #include "Hazel/Core/Buffer.h" #include "Hazel/Core/FileSystem.h" +#include "Hazel/Project/Project.h" #include "mono/jit/jit.h" #include "mono/metadata/assembly.h" #include "mono/metadata/attrdefs.h" @@ -170,7 +171,12 @@ namespace Hazel bool AssemblyReloading = false; // Mono C# debug +#ifdef HZ_DEBUG bool EnableDebugging = true; +#else + bool EnableDebugging = false; +#endif + // runtime Scene* SceneContext = nullptr; @@ -204,7 +210,8 @@ namespace Hazel return; } - status = LoadAppAssemble("Resources/Scripts/Sandbox.dll"); + const auto modulePath = Project::GetAssetsDirectory() / Project::GetActive()->GetConfig().ScriptModulePath; + status = LoadAppAssemble(modulePath); if (!status) { HZ_CORE_ERROR("[ScriptEngine] Could not load app assembly."); @@ -498,7 +505,11 @@ namespace Hazel MonoObject* ScriptEngine::GetManagedInstance(const UUID uuid) { - HZ_CORE_ASSERT(s_Data->EntityInstances.contains(uuid),"could not find entity"); + if (!s_Data->EntityInstances.contains(uuid)) + { + HZ_CORE_ERROR("could not find entity : {0}", (uint64_t)uuid); + return nullptr; + } return s_Data->EntityInstances.at(uuid)->GetManagedObject(); } diff --git a/Hazel/src/Hazel/Scripting/ScriptGlue.cpp b/Hazel/src/Hazel/Scripting/ScriptGlue.cpp index 578fd4c..8c8f432 100644 --- a/Hazel/src/Hazel/Scripting/ScriptGlue.cpp +++ b/Hazel/src/Hazel/Scripting/ScriptGlue.cpp @@ -12,6 +12,7 @@ #include "Hazel/Core/assert.h" #include "mono/jit/jit.h" #include "box2d/box2d.h" +#include "Hazel/Physics/Physics2D.h" namespace Hazel { @@ -123,6 +124,41 @@ namespace Hazel b2Body_ApplyLinearImpulseToCenter(rb2d.RuntimeBody, b2Vec2(impules->x, impules->y), wake); } + static void RigidBody2DComponent_GetLinearVelocity(const UUID entityID, glm::vec2* outLinearVelocity) + { + Scene* scene = ScriptEngine::GetSceneContext(); + HZ_CORE_ASSERT(scene, "sceneContext is Not exist!"); + Entity entity = scene->GetEntityByUUID(entityID); + HZ_CORE_ASSERT(entity, "entity is Not exist!"); + + const auto& rb2d = entity.GetComponent(); + auto [x, y] = b2Body_GetLinearVelocity(rb2d.RuntimeBody); + + *outLinearVelocity = {x,y}; + } + + static RigidBody2DComponent::BodyType RigidBody2DComponent_GetType(const UUID entityID) + { + Scene* scene = ScriptEngine::GetSceneContext(); + HZ_CORE_ASSERT(scene, "sceneContext is Not exist!"); + Entity entity = scene->GetEntityByUUID(entityID); + HZ_CORE_ASSERT(entity, "entity is Not exist!"); + + const auto& rb2d = entity.GetComponent(); + return Utils::Rigidbody2DTypeFromBox2DBody(b2Body_GetType(rb2d.RuntimeBody)); + } + + static void RigidBody2DComponent_SetType(const UUID entityID, RigidBody2DComponent::BodyType type) + { + Scene* scene = ScriptEngine::GetSceneContext(); + HZ_CORE_ASSERT(scene, "sceneContext is Not exist!"); + Entity entity = scene->GetEntityByUUID(entityID); + HZ_CORE_ASSERT(entity, "entity is Not exist!"); + + const auto& rb2d = entity.GetComponent(); + b2Body_SetType(rb2d.RuntimeBody, Utils::RigidBodyTypeToBox2DBodyType(type)); + } + static bool Input_IsKeyDown(const KeyCode keycode) { @@ -181,6 +217,11 @@ namespace Hazel HZ_ADD_INTERNAL_CALL(RigidBody2DComponent_ApplyLinearImpulse); HZ_ADD_INTERNAL_CALL(RigidBody2DComponent_ApplyLinearImpulseToCenter); + HZ_ADD_INTERNAL_CALL(RigidBody2DComponent_GetLinearVelocity); + HZ_ADD_INTERNAL_CALL(RigidBody2DComponent_GetType); + HZ_ADD_INTERNAL_CALL(RigidBody2DComponent_SetType); + + HZ_ADD_INTERNAL_CALL(Input_IsKeyDown); } } diff --git a/Hazel/src/Hazel/UI/UI.h b/Hazel/src/Hazel/UI/UI.h new file mode 100644 index 0000000..dc5ef58 --- /dev/null +++ b/Hazel/src/Hazel/UI/UI.h @@ -0,0 +1,43 @@ +// +// Created by sfd on 25-10-27. +// + +#ifndef UI_H +#define UI_H +#include "imgui.h" + + +namespace Hazel::UI +{ + struct ScopedStyleColor + { + ScopedStyleColor() = default; + + ScopedStyleColor(const ImGuiCol idx, const ImVec4 color, const bool predicate = true) + : m_Set(predicate) + { + if (predicate) + ImGui::PushStyleColor(idx, color); + } + + ScopedStyleColor(const ImGuiCol idx, const ImU32 color, const bool predicate = true) + : m_Set(predicate) + { + if (predicate) + ImGui::PushStyleColor(idx, color); + } + + ~ScopedStyleColor() + { + if (m_Set) + ImGui::PopStyleColor(); + } + + private: + bool m_Set = false; + }; + +} + + +#endif //UI_H