From fa0ea8166539774ab0064e380c313c449e7b28fe Mon Sep 17 00:00:00 2001 From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com> Date: Thu, 8 May 2025 10:17:26 -0500 Subject: [PATCH] Added modes to Path Follower --- remake/build.log | 4 +- src/src/Components/PathFollowerComponent.cpp | 78 ++++++++++++++------ src/src/Components/PathFollowerComponent.h | 18 +++++ src/src/editor/windows/Inspector.cpp | 6 ++ 4 files changed, 80 insertions(+), 26 deletions(-) diff --git a/remake/build.log b/remake/build.log index 167bf69..98899d3 100644 --- a/remake/build.log +++ b/remake/build.log @@ -1,3 +1 @@ -[COMPILE] g++ -std=c++20 -Wall -g -DGLM_ENABLE_EXPERIMENTAL -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\Components\PathFollowerComponent.cpp -o src\build\Components\PathFollowerComponent.o -[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\AudioPlayerComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PathFollowerComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\audio\AudioEngine.o src\build\core\functions\Prefab.o src\build\core\functions\ScenePacker.o src\build\core\scripts\LuaGlobalBridge.o src\build\core\scripts\ScriptCore.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Popup.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\AudioInfo.o src\build\editor\windows\Inspector.o src\build\editor\windows\LuaGlobals.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o src\build\miniaudio.o src\build\ImGuizmo.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -ldbghelp -lz -[RUN] Executed app.exe successfully. +[COMPILE] g++ -std=c++20 -Wall -g -DGLM_ENABLE_EXPERIMENTAL -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Components\PathFollowerComponent.cpp -o src\build\Components\PathFollowerComponent.o diff --git a/src/src/Components/PathFollowerComponent.cpp b/src/src/Components/PathFollowerComponent.cpp index a46be1b..fe6d367 100644 --- a/src/src/Components/PathFollowerComponent.cpp +++ b/src/src/Components/PathFollowerComponent.cpp @@ -7,16 +7,12 @@ #include "../Entitys/Object.h" #include "../core/utils/ExceptionHandler.h" - using core::types::Vec2; -PathFollowerComponent::PathFollowerComponent(Object* owner) +PathFollowerComponent::PathFollowerComponent(Object *owner) : Component(owner) {} - - - -void PathFollowerComponent::AddTarget(const Vec2& point) +void PathFollowerComponent::AddTarget(const Vec2 &point) { m_targets.push_back(point); } @@ -31,13 +27,16 @@ float PathFollowerComponent::Ease(float t) const { switch (m_easing) { - case EasingFunction::EaseInOut: return t * t * (3 - 2 * t); - case EasingFunction::EaseOutCubic: return 1 - std::pow(1 - t, 3); - default: return t; + case EasingFunction::EaseInOut: + return t * t * (3 - 2 * t); + case EasingFunction::EaseOutCubic: + return 1 - std::pow(1 - t, 3); + default: + return t; } } -float PathFollowerComponent::GetCornerSharpness(const Vec2& a, const Vec2& b, const Vec2& c) const +float PathFollowerComponent::GetCornerSharpness(const Vec2 &a, const Vec2 &b, const Vec2 &c) const { glm::vec2 d1 = glm::normalize(glm::vec2(b - a)); glm::vec2 d2 = glm::normalize(glm::vec2(c - b)); @@ -47,7 +46,8 @@ float PathFollowerComponent::GetCornerSharpness(const Vec2& a, const Vec2& b, co void PathFollowerComponent::Update(float dt) { - if (m_targets.empty()) return; + if (m_targets.empty()) + return; if (!m_initialized) { @@ -61,11 +61,41 @@ void PathFollowerComponent::Update(float dt) if (dist < 1.0f) { - m_currentTarget++; - if (m_currentTarget >= m_targets.size()) + if (m_pathMode == PathMode::Loop) { - m_currentTarget = 0; + m_currentTarget = (m_currentTarget + 1) % m_targets.size(); } + else if (m_pathMode == PathMode::PingPong) + { + if (m_forward) + { + if (m_currentTarget + 1 < m_targets.size()) + m_currentTarget++; + else + { + m_forward = false; + m_currentTarget--; + } + } + else + { + if (m_currentTarget > 0) + m_currentTarget--; + else + { + m_forward = true; + m_currentTarget++; + } + } + } + else if (m_pathMode == PathMode::Stop) + { + if (m_currentTarget + 1 < m_targets.size()) + m_currentTarget++; + else + return; + } + return; } @@ -77,8 +107,7 @@ void PathFollowerComponent::Update(float dt) slowdownFactor = GetCornerSharpness( m_targets[m_currentTarget - 1], m_targets[m_currentTarget], - m_targets[m_currentTarget + 1] - ); + m_targets[m_currentTarget + 1]); } float easedSpeed = Ease(slowdownFactor) * m_speed; @@ -86,17 +115,17 @@ void PathFollowerComponent::Update(float dt) owner->SetLocalPosition(m_currentPosition); } - - -void PathFollowerComponent::Save(YAML::Emitter& out) const +void PathFollowerComponent::Save(YAML::Emitter &out) const { out << YAML::BeginMap; out << YAML::Key << "type" << YAML::Value << GetName(); out << YAML::Key << "speed" << YAML::Value << m_speed; out << YAML::Key << "easing" << YAML::Value << static_cast(m_easing); + out << YAML::Key << "mode" << YAML::Value << static_cast(m_pathMode); + out << YAML::Key << "targets" << YAML::Value << YAML::BeginSeq; - for (const auto& pt : m_targets) + for (const auto &pt : m_targets) { out << YAML::BeginMap; out << YAML::Key << "x" << YAML::Value << pt.x; @@ -107,17 +136,20 @@ void PathFollowerComponent::Save(YAML::Emitter& out) const out << YAML::EndMap; } -void PathFollowerComponent::Load(const YAML::Node& node) +void PathFollowerComponent::Load(const YAML::Node &node) { try { m_speed = node["speed"] ? node["speed"].as() : 100.0f; m_easing = node["easing"] ? static_cast(node["easing"].as()) : EasingFunction::Linear; + if (node["mode"]) + m_pathMode = static_cast(node["mode"].as()); + m_targets.clear(); if (node["targets"]) { - for (const auto& pt : node["targets"]) + for (const auto &pt : node["targets"]) { float x = pt["x"] ? pt["x"].as() : 0.0f; float y = pt["y"] ? pt["y"].as() : 0.0f; @@ -128,7 +160,7 @@ void PathFollowerComponent::Load(const YAML::Node& node) m_currentTarget = 0; m_initialized = false; } - catch (const std::exception& e) + catch (const std::exception &e) { RecoverableError("Failed to load PathFollowerComponent: " + std::string(e.what()), Create::Exceptions::ComponentLoad).Handle(); } diff --git a/src/src/Components/PathFollowerComponent.h b/src/src/Components/PathFollowerComponent.h index ac717a4..f3190ac 100644 --- a/src/src/Components/PathFollowerComponent.h +++ b/src/src/Components/PathFollowerComponent.h @@ -11,6 +11,13 @@ enum class EasingFunction EaseOutCubic }; +enum class PathMode { + Loop, + PingPong, + Stop +}; + + class PathFollowerComponent : public Component { public: @@ -39,12 +46,23 @@ public: m_targets.erase(m_targets.begin() + index); } + PathMode GetPathMode() const { return m_pathMode; } +void SetPathMode(PathMode mode) { m_pathMode = mode; } + +void SetForward(bool forward) { m_forward = forward; } +bool IsForward() const { return m_forward; } + + private: std::vector m_targets; size_t m_currentTarget = 0; float m_speed = 100.0f; EasingFunction m_easing = EasingFunction::Linear; + PathMode m_pathMode = PathMode::Loop; + bool m_forward = true; + + core::types::Vec2 m_currentPosition; bool m_initialized = false; diff --git a/src/src/editor/windows/Inspector.cpp b/src/src/editor/windows/Inspector.cpp index cc6fe9b..64881ac 100644 --- a/src/src/editor/windows/Inspector.cpp +++ b/src/src/editor/windows/Inspector.cpp @@ -774,6 +774,12 @@ void DrawInspectorUI(std::shared_ptr selected) if (ImGui::Combo("Easing", ¤tEasing, easingNames, IM_ARRAYSIZE(easingNames))) pathfollower->SetEasing(static_cast(currentEasing)); + const char* modeNames[] = { "Loop", "PingPong", "Stop" }; + int modeIndex = static_cast(pathfollower->GetPathMode()); + if (ImGui::Combo("Path Mode", &modeIndex, modeNames, IM_ARRAYSIZE(modeNames))) + pathfollower->SetPathMode(static_cast(modeIndex)); + + ImGui::SeparatorText("Path Points"); // Path points