From cd541e7d75f9701d7de733ba24fb476ec9ae1b11 Mon Sep 17 00:00:00 2001 From: Joey Pollack Date: Wed, 7 Sep 2022 13:59:26 -0400 Subject: [PATCH] Adds VelocityComponent and CameraComponent Adds instructions doc explaining the process of adding new components --- docs/creating_components.txt | 7 ++ docs/tasks/Bugs.todo | 1 + src/core/types.h | 3 + src/gui/imgui_ext.cpp | 26 ++++--- src/gui/imgui_ext.h | 6 +- src/renderer/orthographic_camera.cpp | 15 +++++ src/renderer/orthographic_camera.h | 4 ++ src/run_modes/editor/component_guis.cpp | 32 +++++++++ src/run_modes/editor/component_guis.h | 2 + src/run_modes/editor/panels/asset_browser.cpp | 2 +- .../editor/panels/properties_view.cpp | 28 +++++++- .../tools/map_editor/panels/map_canvas.cpp | 2 +- .../testbed/scenes/simple_render_scene.cpp | 2 +- src/world/components.h | 8 +++ src/world/entity.cpp | 67 +++++++++++++++++++ 15 files changed, 189 insertions(+), 16 deletions(-) create mode 100644 docs/creating_components.txt diff --git a/docs/creating_components.txt b/docs/creating_components.txt new file mode 100644 index 0000000..38dfe3c --- /dev/null +++ b/docs/creating_components.txt @@ -0,0 +1,7 @@ +STEPS FOR CREATING A NEW COMPONENT: + +1) add the struct to components.h +2) add the gui code to component_guis.h +3) add the code to call the gui function to properties_view.cpp +4) add the code to add a new instance of the component to selected entity in properties_view's ADD_COMPONENT popup (using PRESENT_COMP_CHOICE) +5) add serialize/deserialize code to entity.cpp \ No newline at end of file diff --git a/docs/tasks/Bugs.todo b/docs/tasks/Bugs.todo index b9792d3..8372ec1 100644 --- a/docs/tasks/Bugs.todo +++ b/docs/tasks/Bugs.todo @@ -1,5 +1,6 @@ High Importance: + ✔ Add Component button on properties view no longer works @critical @done(22-09-07 13:44) ✔ AssetBrowser back button does not stop at the asset root directory @high @done(22-07-05 13:53) ✔ Editor does not get absolute paths from the file browser - replace with NFD dialogs @critical @done(22-05-20 18:36) ✔ The Map Editor does not get the tile maps when a project is opened @high @done (3/3/2022, 2:47:41 PM) diff --git a/src/core/types.h b/src/core/types.h index 875ad21..71f46d9 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -28,6 +28,9 @@ namespace lunarium bool operator==(const Vec2& rhs) const { return (this->X == rhs.X && this->Y == rhs.Y); } bool operator!=(const Vec2& rhs) const { return !((*this) == rhs); } + Vec2() = default; + Vec2(const glm::vec3& rhs) : X(rhs.x), Y(rhs.y) {} + Vec2(T x, T y) : X(x), Y(y) {} operator glm::vec3() { return glm::vec3(X, Y, 0.0f); } }; diff --git a/src/gui/imgui_ext.cpp b/src/gui/imgui_ext.cpp index fe5bb78..1b42f3e 100644 --- a/src/gui/imgui_ext.cpp +++ b/src/gui/imgui_ext.cpp @@ -15,8 +15,9 @@ namespace lunarium { /// This function was taken from the Hazel engine written by Cherno! /// https://github.com/TheCherno/Hazel/blob/master/Hazelnut/src/Panels/SceneHierarchyPanel.cpp - void ImGuiExt::Vec3Control(const std::string& label, glm::vec3& values, float resetValue, float columnWidth) + bool ImGuiExt::Vec3Control(const std::string& label, glm::vec3& values, float resetValue, float columnWidth) { + bool values_updated = false; ImGui::PushID(label.c_str()); ImGui::Columns(2); @@ -40,7 +41,7 @@ namespace lunarium ImGui::PopStyleColor(3); ImGui::SameLine(); - ImGui::DragFloat("##X", &values.x, 0.1f, 0.0f, 0.0f, "%.2f"); + values_updated = ImGui::DragFloat("##X", &values.x, 0.1f, 0.0f, 0.0f, "%.2f") | values_updated; ImGui::PopItemWidth(); ImGui::SameLine(); @@ -54,7 +55,7 @@ namespace lunarium ImGui::PopStyleColor(3); ImGui::SameLine(); - ImGui::DragFloat("##Y", &values.y, 0.1f, 0.0f, 0.0f, "%.2f"); + values_updated = ImGui::DragFloat("##Y", &values.y, 0.1f, 0.0f, 0.0f, "%.2f") | values_updated; ImGui::PopItemWidth(); ImGui::SameLine(); @@ -68,7 +69,7 @@ namespace lunarium ImGui::PopStyleColor(3); ImGui::SameLine(); - ImGui::DragFloat("##Z", &values.z, 0.1f, 0.0f, 0.0f, "%.2f"); + values_updated = ImGui::DragFloat("##Z", &values.z, 0.1f, 0.0f, 0.0f, "%.2f") | values_updated; ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -76,11 +77,14 @@ namespace lunarium ImGui::Columns(1); ImGui::PopID(); + + return values_updated; } - void ImGuiExt::Vec2Control(const std::string& label, glm::vec3& values, float resetValue, float columnWidth) + bool ImGuiExt::Vec2Control(const std::string& label, glm::vec3& values, float resetValue, float columnWidth) { + bool values_updated = false; ImGui::PushID(label.c_str()); ImGui::Columns(2); @@ -104,7 +108,7 @@ namespace lunarium ImGui::PopStyleColor(3); ImGui::SameLine(); - ImGui::DragFloat("##X", &values.x, 0.1f, 0.0f, 0.0f, "%.2f"); + values_updated = ImGui::DragFloat("##X", &values.x, 0.1f, 0.0f, 0.0f, "%.2f") | values_updated; ImGui::PopItemWidth(); ImGui::SameLine(); @@ -118,7 +122,7 @@ namespace lunarium ImGui::PopStyleColor(3); ImGui::SameLine(); - ImGui::DragFloat("##Y", &values.y, 0.1f, 0.0f, 0.0f, "%.2f"); + values_updated = ImGui::DragFloat("##Y", &values.y, 0.1f, 0.0f, 0.0f, "%.2f") | values_updated; ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -126,11 +130,14 @@ namespace lunarium ImGui::Columns(1); ImGui::PopID(); + + return values_updated; } - void ImGuiExt::FloatControl(const std::string& label, float& value, float resetValue, float columnWidth) + bool ImGuiExt::FloatControl(const std::string& label, float& value, float resetValue, float columnWidth) { + bool values_updated = false; ImGui::PushID(label.c_str()); ImGui::Columns(2); @@ -154,7 +161,7 @@ namespace lunarium ImGui::PopStyleColor(3); ImGui::SameLine(); - ImGui::DragFloat("##X", &value, 0.1f, 0.0f, 0.0f, "%.2f"); + values_updated = ImGui::DragFloat("##X", &value, 0.1f, 0.0f, 0.0f, "%.2f"); ImGui::PopItemWidth(); @@ -163,6 +170,7 @@ namespace lunarium ImGui::Columns(1); ImGui::PopID(); + return values_updated; } /// Only works if this is the only item on the line diff --git a/src/gui/imgui_ext.h b/src/gui/imgui_ext.h index bc3a1e8..6ee2a59 100644 --- a/src/gui/imgui_ext.h +++ b/src/gui/imgui_ext.h @@ -21,9 +21,9 @@ namespace lunarium /// This function was taken from the Hazel engine written by Cherno! /// https://github.com/TheCherno/Hazel/blob/master/Hazelnut/src/Panels/SceneHierarchyPanel.cpp - static void Vec3Control(const std::string& label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 100.0f); - static void Vec2Control(const std::string& label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 100.0f); - static void FloatControl(const std::string& label, float& values, float resetValue = 0.0f, float columnWidth = 100.0f); + static bool Vec3Control(const std::string& label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 100.0f); + static bool Vec2Control(const std::string& label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 100.0f); + static bool FloatControl(const std::string& label, float& values, float resetValue = 0.0f, float columnWidth = 100.0f); static void TextCentered(const std::string text); static bool ButtonCentered(const char* label, float alignment = 0.5f); }; diff --git a/src/renderer/orthographic_camera.cpp b/src/renderer/orthographic_camera.cpp index b9220af..2f7af24 100644 --- a/src/renderer/orthographic_camera.cpp +++ b/src/renderer/orthographic_camera.cpp @@ -63,6 +63,21 @@ namespace lunarium RecalculateView(); } + Vec2f OrthographicCamera::GetPosition() const + { + return mPosition; + } + + float OrthographicCamera::GetRotation() const + { + return mRotation; + } + + Sizef OrthographicCamera::GetViewportSize() const + { + return mViewportSize; + } + void OrthographicCamera::RecalculateView() { mProjection = glm::ortho(0.0f, mViewportSize.Width, mViewportSize.Height, 0.0f, -1.0f, 1.0f); diff --git a/src/renderer/orthographic_camera.h b/src/renderer/orthographic_camera.h index 0b4c531..57c65db 100644 --- a/src/renderer/orthographic_camera.h +++ b/src/renderer/orthographic_camera.h @@ -30,6 +30,10 @@ namespace lunarium glm::mat4 GetViewProjection(); Sizef GetViewport() const; + Vec2f GetPosition() const; + float GetRotation() const; + Sizef GetViewportSize() const; + private: void RecalculateView(); diff --git a/src/run_modes/editor/component_guis.cpp b/src/run_modes/editor/component_guis.cpp index 43d4849..30956bd 100644 --- a/src/run_modes/editor/component_guis.cpp +++ b/src/run_modes/editor/component_guis.cpp @@ -59,4 +59,36 @@ namespace lunarium { namespace editor comp.Rotation = glm::radians(rotation); ImGuiExt::Vec2Control("Scale", comp.Scale, 1.0f, 85.0f); } + + + void CompGui::RenderVelocityComp(VelocityComponent& comp) + { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, ImGui::GetStyle().ItemSpacing.y + 10.0f)); + DrawTitle("Velocity Component"); + ImGui::PopStyleVar(); + + ImGuiExt::Vec2Control("Velocity", comp.Velocity, 0.0f, 85.0f); + } + + + void CompGui::RenderCameraComp(CameraComponent& comp) + { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, ImGui::GetStyle().ItemSpacing.y + 10.0f)); + DrawTitle("Camera Component"); + ImGui::PopStyleVar(); + + glm::vec3 pos = comp.Camera.GetPosition(); + if (ImGuiExt::Vec2Control("Position", pos)) + { + comp.Camera.SetPosition(pos); + } + + float rot = comp.Camera.GetRotation(); + ImGui::Text("Rotation Angle: "); + ImGui::SameLine(); + if (ImGui::DragFloat("##rotation", &rot, 0.5f, 0.0f, 360.0f)) + { + comp.Camera.SetRotation(rot); + } + } }} \ No newline at end of file diff --git a/src/run_modes/editor/component_guis.h b/src/run_modes/editor/component_guis.h index 30950ba..71d96ac 100644 --- a/src/run_modes/editor/component_guis.h +++ b/src/run_modes/editor/component_guis.h @@ -18,6 +18,8 @@ namespace lunarium { namespace editor public: static void RenderTagComp(TagComponent& comp); static void RenderTransformComp(TransformComponent& comp); + static void RenderVelocityComp(VelocityComponent& comp); + static void RenderCameraComp(CameraComponent& comp); }; }} diff --git a/src/run_modes/editor/panels/asset_browser.cpp b/src/run_modes/editor/panels/asset_browser.cpp index 7ec07a5..9a156d0 100644 --- a/src/run_modes/editor/panels/asset_browser.cpp +++ b/src/run_modes/editor/panels/asset_browser.cpp @@ -206,7 +206,7 @@ namespace editor { if (ImGui::Selectable((*iter)->GetFileLocation().stem().string().c_str())) { - // TODO: Show properties if this is new selection (meaning wasn't selected last frame) + // Show properties if this is new selection (meaning wasn't selected last frame) // Logger::Info(Editor::LogCat, "Asset selected. Properties shold show in the PropertiesView Panel"); mpEditor->OnAssetSelected((*iter)); } diff --git a/src/run_modes/editor/panels/properties_view.cpp b/src/run_modes/editor/panels/properties_view.cpp index c26418e..b47cb80 100644 --- a/src/run_modes/editor/panels/properties_view.cpp +++ b/src/run_modes/editor/panels/properties_view.cpp @@ -23,6 +23,10 @@ if (ImGui::Selectable(str_name)){\ return false;\ }\ pv->mpSelectedEntity->AddComponent();\ + if (!pv->mpSelectedEntity->HasComponent()) {\ + Logger::Error(Editor::LogCat, "Component not added to entity - unknown error");\ + }\ + Logger::Info(Editor::LogCat, "Component added to entity: %ll", pv->mpSelectedEntity->GetUUID());\ return false;\ } @@ -36,16 +40,22 @@ namespace lunarium { namespace editor AddPopup(Popup::ADD_COMP, "Add Component", [](Panel* p) { PropertiesView* pv = (PropertiesView*)p; + int is_hover = ImGui::IsWindowHovered(); // List components that can be added PRESENT_COMP_CHOICE("Tag Component", TagComponent, pv) PRESENT_COMP_CHOICE("Transform Component", TransformComponent, pv) + PRESENT_COMP_CHOICE("Velocity Component", VelocityComponent, pv) + PRESENT_COMP_CHOICE("Camera Component", CameraComponent, pv) + - if ((ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsWindowHovered())) + if ((ImGui::IsMouseClicked(ImGuiMouseButton_Left) && is_hover < 1)) { return false; } + // ImGui::Text("Is Window Hovered? %d", is_hover); + return true; }).LogIfFailed(Editor::LogCat); @@ -144,6 +154,22 @@ namespace lunarium { namespace editor ImGui::Separator(); } + if (mpSelectedEntity->HasComponent()) + { + ImGui::PopStyleVar(); + CompGui::RenderVelocityComp(mpSelectedEntity->GetComponent()); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, spacing_y)); + ImGui::Separator(); + } + + if (mpSelectedEntity->HasComponent()) + { + ImGui::PopStyleVar(); + CompGui::RenderCameraComp(mpSelectedEntity->GetComponent()); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, spacing_y)); + ImGui::Separator(); + } + // After all components rendered if (ImGuiExt::ButtonCentered("Add Component")) { diff --git a/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp b/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp index 62191ea..3faf1e1 100644 --- a/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp +++ b/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp @@ -23,7 +23,7 @@ namespace lunarium { namespace editor { MapCanvas::MapCanvas(MapEditor* editor) : Panel("Map Canvas", PanelDockZone::DDZ_CENTER, true, ImGuiWindowFlags_NoScrollbar), - mpMapEditor(editor), mpCanvasImage(nullptr), mMap(nullptr), mSelectedTile({-1, -1}), mFrameBuffer(nullptr), mMapSizeChanged(false), + mpMapEditor(editor), mpCanvasImage(nullptr), mMap(nullptr), mSelectedTile({-1, {0, 0}}), mFrameBuffer(nullptr), mMapSizeChanged(false), mZoomFactor(1.0f), mScrollDragged(false), mCurrentRegion({0, 0}), mRegionString("") { mRegionString = std::to_string(mCurrentRegion.X); diff --git a/src/run_modes/testbed/scenes/simple_render_scene.cpp b/src/run_modes/testbed/scenes/simple_render_scene.cpp index 7b552fc..db4149c 100644 --- a/src/run_modes/testbed/scenes/simple_render_scene.cpp +++ b/src/run_modes/testbed/scenes/simple_render_scene.cpp @@ -372,7 +372,7 @@ namespace lunarium ImGui::SetNextItemWidth(65); if (ImGui::InputInt2(id.c_str(), v)) { - mTestMap.SetTile(editor::TileRef {0, v[0], v[1] }, Vec2i { i, j }); + mTestMap.SetTile(editor::TileRef {0, {v[0], v[1]} }, Vec2i { i, j }); } if (j + 1 < mTestMap.GetSizeInTiles().Height) diff --git a/src/world/components.h b/src/world/components.h index 54e9068..b1df777 100644 --- a/src/world/components.h +++ b/src/world/components.h @@ -57,6 +57,14 @@ namespace lunarium } }; + struct VelocityComponent + { + glm::vec3 Velocity = { 0.0f, 0.0f, 0.0f}; + + VelocityComponent() = default; + VelocityComponent(const VelocityComponent&) = default; + }; + struct CameraComponent { OrthographicCamera Camera; diff --git a/src/world/entity.cpp b/src/world/entity.cpp index 9f8e8f8..172cdeb 100644 --- a/src/world/entity.cpp +++ b/src/world/entity.cpp @@ -91,10 +91,45 @@ namespace lunarium components.emplace_back(transform); } + if (HasComponent()) + { + nlohmann::ordered_json velocity; + VelocityComponent& comp = GetComponent(); + velocity["type_name"] = "VelocityComponent"; + + auto& pos = velocity["velocity"]; + pos["x"] = comp.Velocity.x; + pos["y"] = comp.Velocity.y; + pos["z"] = comp.Velocity.z; + + components.emplace_back(velocity); + } + + if (HasComponent()) + { + nlohmann::ordered_json camera; + CameraComponent& comp = GetComponent(); + camera["type_name"] = "CameraComponent"; + + auto& pos = camera["position"]; + pos["x"] = comp.Camera.GetPosition().X; + pos["y"] = comp.Camera.GetPosition().Y; + pos["z"] = 0.0f; + + auto& rot = camera["rotation"]; + rot["degrees"] = comp.Camera.GetRotation(); + + auto& vpsize = camera["viewport_size"]; + vpsize["width"] = comp.Camera.GetViewportSize().Width; + vpsize["height"] = comp.Camera.GetViewportSize().Height; + + components.emplace_back(camera); + } // TODO: ADD CODE TO SERIALIZE ANY NEW COMPONENTS + // Children auto& children = node["children"]; for (int i = 0; i < mChildren.size(); i++) @@ -150,6 +185,38 @@ namespace lunarium AddComponent(position, rotation, scale); } + + if ("VelocityComponent" == comp_type_name) + { + auto& vel = comp["velocity"]; + float x = vel["x"].get(); + float y = vel["y"].get(); + float z = vel["z"].get(); + glm::vec3 velocity(x, y, z); + + AddComponent(velocity); + } + + if ("CameraComponent" == comp_type_name) + { + auto& pos = comp["position"]; + float x = pos["x"].get(); + float y = pos["y"].get(); + float z = pos["z"].get(); + glm::vec3 position(x, y, z); + + auto& rot = comp["rotation"]; + float deg = rot["degrees"]; + + auto& vps = comp["viewport_size"]; + float width = vps["width"].get(); + float height = vps["height"].get(); + + OrthographicCamera cam({x, y}, {width, height}); + cam.SetRotation(deg); + + AddComponent(cam); + } }