diff --git a/StarEditor/assets/scene/3D Cube.starscene b/StarEditor/SandboxProject/Assets/Scenes/3D Cube.starscene similarity index 100% rename from StarEditor/assets/scene/3D Cube.starscene rename to StarEditor/SandboxProject/Assets/Scenes/3D Cube.starscene diff --git a/StarEditor/assets/scene/Physics2D.starscene b/StarEditor/SandboxProject/Assets/Scenes/Physics2D.starscene similarity index 100% rename from StarEditor/assets/scene/Physics2D.starscene rename to StarEditor/SandboxProject/Assets/Scenes/Physics2D.starscene diff --git a/StarEditor/SandboxProject/Assets/Scripts/Source/Player.cs b/StarEditor/SandboxProject/Assets/Scripts/Source/Player.cs index 46b84745..0a911124 100644 --- a/StarEditor/SandboxProject/Assets/Scripts/Source/Player.cs +++ b/StarEditor/SandboxProject/Assets/Scripts/Source/Player.cs @@ -13,7 +13,7 @@ public class Player : Entity private TransformComponent m_Transform; private RigidBody2DComponent m_RigidBody; - public float Speed = 1.0f; + public float Speed; public float Time = 0.0f; void OnCreate() diff --git a/StarEditor/assets/textures/Checkerboard.png b/StarEditor/SandboxProject/Assets/Textures/Checkerboard.png similarity index 100% rename from StarEditor/assets/textures/Checkerboard.png rename to StarEditor/SandboxProject/Assets/Textures/Checkerboard.png diff --git a/StarEditor/assets/textures/starLogo.png b/StarEditor/SandboxProject/Assets/Textures/starLogo.png similarity index 100% rename from StarEditor/assets/textures/starLogo.png rename to StarEditor/SandboxProject/Assets/Textures/starLogo.png diff --git a/StarEditor/SandboxProject/Sandbox.starproj b/StarEditor/SandboxProject/Sandbox.starproj new file mode 100644 index 00000000..b128b227 --- /dev/null +++ b/StarEditor/SandboxProject/Sandbox.starproj @@ -0,0 +1,5 @@ +Project: + Name: Sandbox + StartScene: "Scenes/Physics2D.starscene" + AssetDirectory: "Assets" + ScriptModulePath: "Scripts/Binaries/Sandbox.dll" diff --git a/StarEditor/premake5.lua b/StarEditor/premake5.lua index 8ec2ed07..6ca86a29 100644 --- a/StarEditor/premake5.lua +++ b/StarEditor/premake5.lua @@ -31,6 +31,11 @@ project "StarEditor" filter "system:windows" systemversion "latest" + postbuildcommands { + "{COPYDIR} %{wks.location}/StarEditor/assets %{wks.location}/bin/" .. outputdir .. "/StarEditor/assets", + "{COPYDIR} %{wks.location}/StarEditor/Resources %{wks.location}/bin/" .. outputdir .. "/StarEditor/Resources", + "{COPYFILE} %{wks.location}/StarEditor/imgui.ini %{wks.location}/bin/" .. outputdir .. "/StarEditor/imgui.ini", + } filter "configurations:Debug" defines "SE_DEBUG" @@ -47,11 +52,5 @@ project "StarEditor" runtime "Release" optimize "on" - postbuildcommands { - "{COPYDIR} %{wks.location}/StarEditor/assets %{wks.location}/bin/" .. outputdir .. "/StarEditor/assets", - "{COPYDIR} %{wks.location}/StarEditor/Resources %{wks.location}/bin/" .. outputdir .. "/StarEditor/Resources", - "{COPYFILE} %{wks.location}/StarEditor/imgui.ini %{wks.location}/bin/" .. outputdir .. "/StarEditor/imgui.ini", - } - filter "action:vs2022" buildoptions { "/utf-8" } diff --git a/StarEditor/src/EditorLayer.cpp b/StarEditor/src/EditorLayer.cpp index ccc7745f..5686c23e 100644 --- a/StarEditor/src/EditorLayer.cpp +++ b/StarEditor/src/EditorLayer.cpp @@ -15,8 +15,6 @@ namespace StarEngine { - extern const std::filesystem::path g_AssetPath; - EditorLayer::EditorLayer() : Layer("EditorLayer"), m_CameraController(1280.0f / 720.0f, true), m_SquareColor({ 0.2f, 0.3f, 0.8f, 1.0f }) { @@ -47,9 +45,18 @@ namespace StarEngine { auto commandLineArgs = Application::Get().GetSpecification().CommandLineArgs; if (commandLineArgs.Count > 1) { - auto sceneFilePath = commandLineArgs[1]; - SceneSerializer serializer(m_ActiveScene); - serializer.Deserialize(sceneFilePath); + auto projectFilePath = commandLineArgs[1]; + OpenProject(projectFilePath); + } + else + { + // TODO: prompt the user to select a directory + // NewProject(); + + if (!OpenProject()) + { + Application::Get().Close(); + } } m_EditorCamera = EditorCamera(30.0f, 1.778f, 0.1f, 1000.0f); @@ -193,27 +200,21 @@ namespace StarEngine { { if (ImGui::BeginMenu("File")) { - // Disabling fullscreen would allow the window to be moved to the front of other windows, - // which we can't undo at the moment without finer window depth/z control. - //ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen_persistant);1 + if (ImGui::MenuItem("Open Project...", "Ctrl+O")) + OpenProject(); - if (ImGui::MenuItem("New", "Ctrl+N")) - { - NewScene(); - } + ImGui::Separator(); - if (ImGui::MenuItem("Open...", "Ctrl+O")) - { - OpenScene(); - } + if (ImGui::MenuItem("New Scene", "Ctrl+N")) + NewScene(); - if (ImGui::MenuItem("Save", "Ctrl+S")) + if (ImGui::MenuItem("Save Scene", "Ctrl+S")) SaveScene(); - if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S")) - { + if (ImGui::MenuItem("Save Scene As...", "Ctrl+Shift+S")) SaveSceneAs(); - } + + ImGui::Separator(); if (ImGui::MenuItem("Exit")) Application::Get().Close(); @@ -233,15 +234,17 @@ namespace StarEngine { } m_SceneHierarchyPanel.OnImGuiRender(); - m_ContentBrowserPanel.OnImGuiRender(); + m_ContentBrowserPanel->OnImGuiRender(); //Camera Info ImGui::Begin("Stats"); +#if 0 std::string name = "None"; if (m_HoveredEntity) name = m_HoveredEntity.GetComponent().Tag; ImGui::Text("Hovered Entity: %s", name.c_str()); +#endif auto stats = Renderer2D::GetStats(); ImGui::Text("Renderer2D Stats:"); @@ -287,7 +290,7 @@ namespace StarEngine { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROWSER_ITEM")) { const wchar_t* path = (const wchar_t*)payload->Data; - OpenScene(std::filesystem::path(g_AssetPath) / path); + OpenScene(path); } ImGui::EndDragDropTarget(); } @@ -477,7 +480,7 @@ namespace StarEngine { case Key::O: { if (control) - OpenScene(); + OpenProject(); break; } @@ -536,6 +539,20 @@ namespace StarEngine { break; } + case Key::Delete: + { + if (Application::Get().GetImGuiLayer()->GetActiveWidgetID() == 0) + { + Entity selectedEntity = m_SceneHierarchyPanel.GetSelectedEntity(); + if (selectedEntity) + { + m_SceneHierarchyPanel.SetSelectedEntity({}); + m_ActiveScene->DestroyEntity(selectedEntity); + } + } + break; + } + default: break; } @@ -615,6 +632,37 @@ namespace StarEngine { Renderer2D::EndScene(); } + void EditorLayer::NewProject() + { + Project::New(); + } + + void EditorLayer::OpenProject(const std::filesystem::path& path) + { + if (Project::Load(path)) + { + ScriptEngine::Init(); + + auto startScenePath = Project::GetAssetFileSystemPath(Project::GetActive()->GetConfig().StartScene); + OpenScene(startScenePath); + m_ContentBrowserPanel = CreateScope(); + } + } + + bool EditorLayer::OpenProject() + { + std::string filepath = FileDialogs::OpenFile("Star Project (*.starproj)\0*.starproj\0"); + if (filepath.empty()) + return false; + + OpenProject(filepath); + return true; + } + + void EditorLayer::SaveProject() + { + // Project::SaveActive(); + } void EditorLayer::NewScene() { @@ -738,7 +786,10 @@ namespace StarEngine { Entity selectedEntity = m_SceneHierarchyPanel.GetSelectedEntity(); if (selectedEntity) - m_EditorScene->DuplicateEntity(selectedEntity); + { + Entity newEntity = m_EditorScene->DuplicateEntity(selectedEntity); + m_SceneHierarchyPanel.SetSelectedEntity(newEntity); + } } } diff --git a/StarEditor/src/EditorLayer.h b/StarEditor/src/EditorLayer.h index 7c40c54b..31b60c15 100644 --- a/StarEditor/src/EditorLayer.h +++ b/StarEditor/src/EditorLayer.h @@ -30,6 +30,11 @@ namespace StarEngine void OnOverlayRender(); + void NewProject(); + bool OpenProject(); + void OpenProject(const std::filesystem::path& path); + void SaveProject(); + void NewScene(); void OpenScene(); void OpenScene(const std::filesystem::path& path); @@ -90,7 +95,7 @@ namespace StarEngine // Panels SceneHierarchyPanel m_SceneHierarchyPanel; - ContentBrowserPanel m_ContentBrowserPanel; + Scope m_ContentBrowserPanel; // Editor resources Ref m_IconPlay, m_IconPause, m_IconStep, m_IconSimulate, m_IconStop; diff --git a/StarEditor/src/Panels/ContentBrowserPanel.cpp b/StarEditor/src/Panels/ContentBrowserPanel.cpp index dc6c84bd..56fb25cc 100644 --- a/StarEditor/src/Panels/ContentBrowserPanel.cpp +++ b/StarEditor/src/Panels/ContentBrowserPanel.cpp @@ -1,15 +1,14 @@ #include "sepch.h" #include "ContentBrowserPanel.h" +#include "StarEngine/Project/Project.h" + #include namespace StarEngine { - // Once we have projects, change this - extern const std::filesystem::path g_AssetPath = "assets"; - ContentBrowserPanel::ContentBrowserPanel() - : m_CurrentDirectory(g_AssetPath) + : 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"); @@ -19,7 +18,7 @@ namespace StarEngine { ImGui::Begin("Content Browser"); - if (m_CurrentDirectory != std::filesystem::path(g_AssetPath)) + if (m_CurrentDirectory != std::filesystem::path(m_BaseDirectory)) { if (ImGui::Button("<-")) { @@ -50,7 +49,7 @@ namespace StarEngine if (ImGui::BeginDragDropSource()) { - auto relativePath = std::filesystem::relative(path, g_AssetPath); + 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(); diff --git a/StarEditor/src/Panels/ContentBrowserPanel.h b/StarEditor/src/Panels/ContentBrowserPanel.h index 85420588..c30c24c7 100644 --- a/StarEditor/src/Panels/ContentBrowserPanel.h +++ b/StarEditor/src/Panels/ContentBrowserPanel.h @@ -13,6 +13,7 @@ namespace StarEngine void OnImGuiRender(); private: + std::filesystem::path m_BaseDirectory; std::filesystem::path m_CurrentDirectory; Ref m_DirectoryIcon; diff --git a/StarEditor/src/Panels/SceneHierarchyPanel.cpp b/StarEditor/src/Panels/SceneHierarchyPanel.cpp index 5a4fa036..4f1ed00f 100644 --- a/StarEditor/src/Panels/SceneHierarchyPanel.cpp +++ b/StarEditor/src/Panels/SceneHierarchyPanel.cpp @@ -2,6 +2,7 @@ #include "StarEngine/Scene/Components.h" #include "StarEngine/Scripting/ScriptEngine.h" +#include "StarEngine/UI/UI.h" #include #include @@ -19,9 +20,6 @@ namespace StarEngine { - // Once we have projects, change this{ - extern const std::filesystem::path g_AssetPath; - SceneHierarchyPanel::SceneHierarchyPanel(const Ref& context) { SetContext(context); @@ -330,11 +328,13 @@ namespace StarEngine 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)); + 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; + return; + } // Fields bool sceneRunning = scene->IsRunning(); @@ -397,9 +397,6 @@ namespace StarEngine } } } - - if (!scriptClassExists) - ImGui::PopStyleColor(); }); DrawComponent("Sprite Renderer", entity, [](auto& component) @@ -412,7 +409,7 @@ namespace StarEngine if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROWSER_ITEM")) { const wchar_t* path = (const wchar_t*)payload->Data; - std::filesystem::path texturePath = std::filesystem::path(g_AssetPath) / path; + std::filesystem::path texturePath(path); Ref texture = Texture2D::Create(texturePath.string()); if (texture->IsLoaded()) component.Texture = texture; diff --git a/StarEngine-ScriptCore/Source/StarEngine/InternalCalls.cs b/StarEngine-ScriptCore/Source/StarEngine/InternalCalls.cs index 5f732ff3..93e509e8 100644 --- a/StarEngine-ScriptCore/Source/StarEngine/InternalCalls.cs +++ b/StarEngine-ScriptCore/Source/StarEngine/InternalCalls.cs @@ -22,6 +22,13 @@ public static class InternalCalls [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static void RigidBody2DComponent_ApplyLinearImpulse(ulong entityID, ref Vector2 impulse, ref Vector2 point, 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 type); + [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static void RigidBody2DComponent_ApplyLinearImpulseToCenter(ulong entityID, ref Vector2 impulse, bool wake); [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/StarEngine-ScriptCore/Source/StarEngine/Scene/Components.cs b/StarEngine-ScriptCore/Source/StarEngine/Scene/Components.cs index fc24b2ac..49b5916d 100644 --- a/StarEngine-ScriptCore/Source/StarEngine/Scene/Components.cs +++ b/StarEngine-ScriptCore/Source/StarEngine/Scene/Components.cs @@ -30,6 +30,23 @@ public Vector3 Translation 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 worldPosition, bool wake) { InternalCalls.RigidBody2DComponent_ApplyLinearImpulse(Entity.ID, ref impulse, ref worldPosition, wake); diff --git a/StarEngine-ScriptCore/Source/StarEngine/Vector2.cs b/StarEngine-ScriptCore/Source/StarEngine/Vector2.cs index 7dc613af..9f3ba905 100644 --- a/StarEngine-ScriptCore/Source/StarEngine/Vector2.cs +++ b/StarEngine-ScriptCore/Source/StarEngine/Vector2.cs @@ -1,4 +1,6 @@ -namespace StarEngine +using System; + +namespace StarEngine { public struct Vector2 { @@ -28,5 +30,14 @@ public Vector2(float x, float y) return new Vector2(vector.X * scalar, vector.Y * scalar); } + public float LengthSquared() + { + return X * X + Y * Y; + } + + public float Length() + { + return (float)Math.Sqrt(LengthSquared()); + } } } diff --git a/StarEngine/premake5.lua b/StarEngine/premake5.lua index 89939a67..add3ce29 100644 --- a/StarEngine/premake5.lua +++ b/StarEngine/premake5.lua @@ -26,7 +26,8 @@ project "StarEngine" defines { "_CRT_SECURE_NO_WARNINGS", - "GLFW_INCLUDE_NONE" + "GLFW_INCLUDE_NONE", + "YAML_CPP_STATIC_DEFINE" } includedirs @@ -53,7 +54,7 @@ project "StarEngine" "GLFW", "GLAD", "imgui", - "opengl32.lib", + "opengl32", "%{Library.mono}", "yaml-cpp", "Box2D", diff --git a/StarEngine/src/StarEngine.h b/StarEngine/src/StarEngine.h index 4ad5e188..6456c547 100644 --- a/StarEngine/src/StarEngine.h +++ b/StarEngine/src/StarEngine.h @@ -26,6 +26,7 @@ #include "StarEngine/Scene/Components.h" #include "StarEngine/Scene/ScriptableEntity.h" +#include "StarEngine/Project/Project.h" #include "StarEngine/Renderer/Buffer.h" #include "StarEngine/Renderer/Shader.h" diff --git a/StarEngine/src/StarEngine/Core/Application.cpp b/StarEngine/src/StarEngine/Core/Application.cpp index 4567a079..d3cb8695 100644 --- a/StarEngine/src/StarEngine/Core/Application.cpp +++ b/StarEngine/src/StarEngine/Core/Application.cpp @@ -28,7 +28,6 @@ namespace StarEngine m_Window->SetEventCallback(SE_BIND_EVENT_FN(Application::OnEvent)); Renderer::Init(); - ScriptEngine::Init(); m_ImGuiLayer = new ImGuiLayer(); PushOverlay(m_ImGuiLayer); diff --git a/StarEngine/src/StarEngine/ImGui/ImGuiLayer.cpp b/StarEngine/src/StarEngine/ImGui/ImGuiLayer.cpp index 9a401b6f..3108051b 100644 --- a/StarEngine/src/StarEngine/ImGui/ImGuiLayer.cpp +++ b/StarEngine/src/StarEngine/ImGui/ImGuiLayer.cpp @@ -4,6 +4,8 @@ #include "StarEngine/Core/Application.h" #include +#include + #include #include @@ -150,4 +152,9 @@ namespace StarEngine { colors[ImGuiCol_TitleBgCollapsed] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; } + uint32_t ImGuiLayer::GetActiveWidgetID() const + { + return GImGui->ActiveId; + } + } diff --git a/StarEngine/src/StarEngine/ImGui/ImGuiLayer.h b/StarEngine/src/StarEngine/ImGui/ImGuiLayer.h index 4a270938..2b9b4c98 100644 --- a/StarEngine/src/StarEngine/ImGui/ImGuiLayer.h +++ b/StarEngine/src/StarEngine/ImGui/ImGuiLayer.h @@ -24,6 +24,8 @@ namespace StarEngine { void BlockEvents(bool block) { m_BlockEvents = block; } void SetDarkThemeColors(); + + uint32_t GetActiveWidgetID() const; private: bool m_BlockEvents = true; }; diff --git a/StarEngine/src/StarEngine/Physics/Physics2D.h b/StarEngine/src/StarEngine/Physics/Physics2D.h new file mode 100644 index 00000000..a5e822ad --- /dev/null +++ b/StarEngine/src/StarEngine/Physics/Physics2D.h @@ -0,0 +1,39 @@ +#pragma once + +#include "StarEngine/Scene/Components.h" + +#include "box2d/b2_body.h" + +namespace StarEngine { + + namespace Utils { + + inline b2BodyType RigidBody2DTypeToBox2DBody(RigidBody2DComponent::BodyType bodyType) + { + switch (bodyType) + { + case RigidBody2DComponent::BodyType::Static: return b2_staticBody; + case RigidBody2DComponent::BodyType::Dynamic: return b2_dynamicBody; + case RigidBody2DComponent::BodyType::Kinematic: return b2_kinematicBody; + } + + SE_CORE_ASSERT(false, "Unknown body type"); + return b2_staticBody; + } + + inline RigidBody2DComponent::BodyType RigidBody2DTypeFromBox2DBody(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; + } + + SE_CORE_ASSERT(false, "Unknown body type"); + return RigidBody2DComponent::BodyType::Static; + } + + } + +} diff --git a/StarEngine/src/StarEngine/Project/Project.cpp b/StarEngine/src/StarEngine/Project/Project.cpp new file mode 100644 index 00000000..8334dee4 --- /dev/null +++ b/StarEngine/src/StarEngine/Project/Project.cpp @@ -0,0 +1,41 @@ +#include "sepch.h" +#include "Project.h" + +#include "ProjectSerializer.h" + +namespace StarEngine { + + 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.parent_path(); + s_ActiveProject = project; + return s_ActiveProject; + } + + 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/StarEngine/src/StarEngine/Project/Project.h b/StarEngine/src/StarEngine/Project/Project.h new file mode 100644 index 00000000..0fbbb6c8 --- /dev/null +++ b/StarEngine/src/StarEngine/Project/Project.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +#include "StarEngine/Core/Base.h" + +namespace StarEngine { + + struct ProjectConfig + { + std::string Name = "Untitled"; + + std::filesystem::path StartScene; + + std::filesystem::path AssetDirectory; + std::filesystem::path ScriptModulePath; + }; + + class Project + { + public: + static const std::filesystem::path& GetProjectDirectory() + { + SE_CORE_ASSERT(s_ActiveProject); + return s_ActiveProject->m_ProjectDirectory; + } + + static std::filesystem::path GetAssetDirectory() + { + SE_CORE_ASSERT(s_ActiveProject); + return GetProjectDirectory() / s_ActiveProject->m_Config.AssetDirectory; + } + + // TODO: move to asset manager when we have one + static std::filesystem::path GetAssetFileSystemPath(const std::filesystem::path& path) + { + SE_CORE_ASSERT(s_ActiveProject); + return GetAssetDirectory() / 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; + }; + +} diff --git a/StarEngine/src/StarEngine/Project/ProjectSerializer.cpp b/StarEngine/src/StarEngine/Project/ProjectSerializer.cpp new file mode 100644 index 00000000..64a597cc --- /dev/null +++ b/StarEngine/src/StarEngine/Project/ProjectSerializer.cpp @@ -0,0 +1,75 @@ +#include "sepch.h" +#include "ProjectSerializer.h" + +#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) + : m_Project(project) + { + } + + bool ProjectSerializer::Serialize(const std::filesystem::path& filepath) + { + 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 << "AssetDirectory" << YAML::Value << config.AssetDirectory.string(); + out << YAML::Key << "ScriptModulePath" << YAML::Value << config.ScriptModulePath.string(); + out << YAML::EndMap; // Project + } + out << YAML::EndMap; // Root + } + + std::ofstream fout(filepath); + fout << out.c_str(); + + return true; + } + + bool ProjectSerializer::Deserialize(const std::filesystem::path& filepath) + { + auto& config = m_Project->GetConfig(); + + YAML::Node data; + try + { + data = YAML::LoadFile(filepath.string()); + } + catch (YAML::ParserException e) + { + SE_CORE_ERROR("Failed to load project file '{0}'\n {1}", filepath, e.what()); + return false; + } + + auto projectNode = data["Project"]; + if (!projectNode) + return false; + + config.Name = projectNode["Name"].as(); + config.StartScene = projectNode["StartScene"].as(); + config.AssetDirectory = projectNode["AssetDirectory"].as(); + config.ScriptModulePath = projectNode["ScriptModulePath"].as(); + return true; + } + +} diff --git a/StarEngine/src/StarEngine/Project/ProjectSerializer.h b/StarEngine/src/StarEngine/Project/ProjectSerializer.h new file mode 100644 index 00000000..093e8754 --- /dev/null +++ b/StarEngine/src/StarEngine/Project/ProjectSerializer.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Project.h" + +namespace StarEngine +{ + class ProjectSerializer + { + public: + ProjectSerializer(Ref project); + + bool Serialize(const std::filesystem::path& filepath); + bool Deserialize(const std::filesystem::path& filepath); + private: + Ref m_Project; + }; + +} diff --git a/StarEngine/src/StarEngine/Scene/Scene.cpp b/StarEngine/src/StarEngine/Scene/Scene.cpp index af1a63a6..a956f385 100644 --- a/StarEngine/src/StarEngine/Scene/Scene.cpp +++ b/StarEngine/src/StarEngine/Scene/Scene.cpp @@ -5,6 +5,7 @@ #include "StarEngine/Scene/ScriptableEntity.h" #include "StarEngine/Scripting/ScriptEngine.h" #include "StarEngine/Renderer/Renderer2D.h" +#include "StarEngine/Physics/Physics2D.h" #include "StarEngine/Scene/Entity.h" @@ -19,19 +20,6 @@ namespace StarEngine { - static b2BodyType RigidBody2DTypeToBox2DBody(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; - } - - SE_CORE_ASSERT(false, "Unknown RigidBody2DComponent::BodyType!"); - return b2_staticBody; - } - Scene::Scene() { } @@ -125,8 +113,8 @@ namespace StarEngine { void Scene::DestroyEntity(Entity entity) { - m_Registry.destroy(entity); m_EntityMap.erase(entity.GetUUID()); + m_Registry.destroy(entity); } void Scene::OnRuntimeStart() @@ -174,7 +162,6 @@ namespace StarEngine { { // Update scripts { - // C# Entity OnUpdate auto view = m_Registry.view(); for (auto e : view) { @@ -343,10 +330,13 @@ namespace StarEngine { m_StepFrames = frames; } - void Scene::DuplicateEntity(Entity entity) + Entity Scene::DuplicateEntity(Entity entity) { - Entity newEntity = CreateEntity(entity.GetName()); + // Copy name because we're going to modify component data structure + std::string name = entity.GetName(); + Entity newEntity = CreateEntity(name); CopyComponentIfExists(AllComponents{}, newEntity, entity); + return newEntity; } Entity Scene::FindEntityByName(std::string_view name) @@ -381,7 +371,7 @@ namespace StarEngine { auto& rb2d = entity.GetComponent(); b2BodyDef bodyDef; - bodyDef.type = RigidBody2DTypeToBox2DBody(rb2d.Type); + bodyDef.type = Utils::RigidBody2DTypeToBox2DBody(rb2d.Type); bodyDef.position.Set(transform.Translation.x, transform.Translation.y); bodyDef.angle = transform.Rotation.z; diff --git a/StarEngine/src/StarEngine/Scene/Scene.h b/StarEngine/src/StarEngine/Scene/Scene.h index 548d9d6b..6882beac 100644 --- a/StarEngine/src/StarEngine/Scene/Scene.h +++ b/StarEngine/src/StarEngine/Scene/Scene.h @@ -35,7 +35,7 @@ namespace StarEngine { void OnUpdateEditor(Timestep ts, 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 GetEntityByUUID(UUID uuid); diff --git a/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp b/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp index af903b6e..ef338e3e 100644 --- a/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp +++ b/StarEngine/src/StarEngine/Scene/SceneSerializer.cpp @@ -6,6 +6,8 @@ #include "StarEngine/Scripting/ScriptEngine.h" #include "StarEngine/Core/UUID.h" +#include "StarEngine/Project/Project.h" + #include #include @@ -106,6 +108,7 @@ namespace YAML { }; } + namespace StarEngine { #define WRITE_SCRIPT_FIELD(FieldType, Type) \ @@ -516,7 +519,11 @@ namespace StarEngine { src.Color = spriteRendererComponent["Color"].as(); if (spriteRendererComponent["TexturePath"]) - src.Texture = Texture2D::Create(spriteRendererComponent["TexturePath"].as()); + { + std::string texturePath = spriteRendererComponent["TexturePath"].as(); + auto path = Project::GetAssetFileSystemPath(texturePath); + src.Texture = Texture2D::Create(path.string()); + } if (spriteRendererComponent["TilingFactor"]) src.TilingFactor = spriteRendererComponent["TilingFactor"].as(); diff --git a/StarEngine/src/StarEngine/Scripting/ScriptEngine.cpp b/StarEngine/src/StarEngine/Scripting/ScriptEngine.cpp index af19d56d..7d089337 100644 --- a/StarEngine/src/StarEngine/Scripting/ScriptEngine.cpp +++ b/StarEngine/src/StarEngine/Scripting/ScriptEngine.cpp @@ -17,6 +17,8 @@ #include "StarEngine/Core/Buffer.h" #include "StarEngine/Core/FileSystem.h" +#include "StarEngine/Project/Project.h" + namespace fmt { template <> struct formatter : formatter { @@ -191,7 +193,9 @@ namespace StarEngine { SE_CORE_ERROR("[ScriptEngine] Could not load StarEngine-ScriptCore assembly."); return; } - status = LoadAppAssembly("SandboxProject/Assets/Scripts/Binaries/Sandbox.dll"); + + auto scriptModulePath = Project::GetAssetDirectory() / Project::GetActive()->GetConfig().ScriptModulePath; + status = LoadAppAssembly(scriptModulePath); if (!status) { SE_CORE_ERROR("[ScriptEngine] Could not load app assembly."); diff --git a/StarEngine/src/StarEngine/Scripting/ScriptGlue.cpp b/StarEngine/src/StarEngine/Scripting/ScriptGlue.cpp index 6f47710f..cac91901 100644 --- a/StarEngine/src/StarEngine/Scripting/ScriptGlue.cpp +++ b/StarEngine/src/StarEngine/Scripting/ScriptGlue.cpp @@ -9,6 +9,8 @@ #include "StarEngine/Scene/Scene.h" #include "StarEngine/Scene/Entity.h" +#include "StarEngine/Physics/Physics2D.h" + #include "mono/metadata/object.h" #include "mono/metadata/reflection.h" @@ -126,6 +128,43 @@ namespace StarEngine { body->ApplyLinearImpulseToCenter(b2Vec2(impulse->x, impulse->y), wake); } + static void RigidBody2DComponent_GetLinearVelocity(UUID entityID, glm::vec2* outLinearVelocity) + { + Scene* scene = ScriptEngine::GetSceneContext(); + SE_CORE_ASSERT(scene); + Entity entity = scene->GetEntityByUUID(entityID); + SE_CORE_ASSERT(entity); + + auto& rb2d = entity.GetComponent(); + b2Body* body = (b2Body*)rb2d.RuntimeBody; + const b2Vec2& linearVelocity = body->GetLinearVelocity(); + *outLinearVelocity = glm::vec2(linearVelocity.x, linearVelocity.y); + } + + static RigidBody2DComponent::BodyType RigidBody2DComponent_GetType(UUID entityID) + { + Scene* scene = ScriptEngine::GetSceneContext(); + SE_CORE_ASSERT(scene); + Entity entity = scene->GetEntityByUUID(entityID); + SE_CORE_ASSERT(entity); + + auto& rb2d = entity.GetComponent(); + b2Body* body = (b2Body*)rb2d.RuntimeBody; + return Utils::RigidBody2DTypeFromBox2DBody(body->GetType()); + } + + static void RigidBody2DComponent_SetType(UUID entityID, RigidBody2DComponent::BodyType bodyType) + { + Scene* scene = ScriptEngine::GetSceneContext(); + SE_CORE_ASSERT(scene); + Entity entity = scene->GetEntityByUUID(entityID); + SE_CORE_ASSERT(entity); + + auto& rb2d = entity.GetComponent(); + b2Body* body = (b2Body*)rb2d.RuntimeBody; + body->SetType(Utils::RigidBody2DTypeToBox2DBody(bodyType)); + } + static bool Input_IsKeyDown(KeyCode keycode) { return Input::IsKeyPressed(keycode); @@ -179,6 +218,9 @@ namespace StarEngine { SE_ADD_INTERNAL_CALL(RigidBody2DComponent_ApplyLinearImpulse); SE_ADD_INTERNAL_CALL(RigidBody2DComponent_ApplyLinearImpulseToCenter); + SE_ADD_INTERNAL_CALL(RigidBody2DComponent_GetLinearVelocity); + SE_ADD_INTERNAL_CALL(RigidBody2DComponent_GetType); + SE_ADD_INTERNAL_CALL(RigidBody2DComponent_SetType); SE_ADD_INTERNAL_CALL(Input_IsKeyDown); } diff --git a/StarEngine/src/StarEngine/UI/UI.h b/StarEngine/src/StarEngine/UI/UI.h new file mode 100644 index 00000000..30b0dee9 --- /dev/null +++ b/StarEngine/src/StarEngine/UI/UI.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +namespace StarEngine::UI { + + struct ScopedStyleColor + { + ScopedStyleColor() = default; + + ScopedStyleColor(ImGuiCol idx, ImVec4 color, bool predicate = true) + : m_Set(predicate) + { + if (predicate) + ImGui::PushStyleColor(idx, color); + } + + ScopedStyleColor(ImGuiCol idx, ImU32 color, bool predicate = true) + : m_Set(predicate) + { + if (predicate) + ImGui::PushStyleColor(idx, color); + } + + ~ScopedStyleColor() + { + if (m_Set) + ImGui::PopStyleColor(); + } + private: + bool m_Set = false; + }; + + +} diff --git a/scripts/Setup.py b/scripts/Setup.py index 41be9dbd..848ec901 100644 --- a/scripts/Setup.py +++ b/scripts/Setup.py @@ -26,4 +26,3 @@ print("\nSetup completed!") else: print("StarEngine requires Premake to generate project files.") - diff --git a/scripts/Win-GenProjects.bat b/scripts/Win-GenProjects.bat index f7299e16..44d898b7 100644 --- a/scripts/Win-GenProjects.bat +++ b/scripts/Win-GenProjects.bat @@ -1,4 +1,5 @@ -pushd ..\ +@echo off +pushd %~dp0\..\ call vendor\premake\bin\premake5.exe vs2022 popd -PAUSE \ No newline at end of file +PAUSE