Added Excapt to deselect and more gizmos

This commit is contained in:
OusmBlueNinja 2025-05-08 11:26:12 -05:00
parent fa0ea81665
commit 5efe2e0b14
6 changed files with 1518 additions and 1337 deletions

View File

@ -43,7 +43,7 @@ DockId=0x00000019,0
[Window][Console] [Window][Console]
Pos=390,680 Pos=390,680
Size=880,273 Size=880,497
Collapsed=0 Collapsed=0
DockId=0x0000001B,0 DockId=0x0000001B,0
@ -137,7 +137,7 @@ Collapsed=0
[Window][Lua Globals] [Window][Lua Globals]
Pos=1272,680 Pos=1272,680
Size=303,273 Size=303,497
Collapsed=0 Collapsed=0
DockId=0x0000001C,0 DockId=0x0000001C,0

View File

@ -1 +1,2 @@
[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 [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\Engine.cpp -o src\build\Engine.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

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,9 @@
static constexpr float PI = 3.14159265358979323846f;
class Object; class Object;

View File

@ -44,13 +44,15 @@ float PathFollowerComponent::GetCornerSharpness(const Vec2 &a, const Vec2 &b, co
return glm::clamp(angle / 180.0f, 0.1f, 1.0f); return glm::clamp(angle / 180.0f, 0.1f, 1.0f);
} }
void PathFollowerComponent::Update(float dt) void PathFollowerComponent::Update(float dt)
{ {
if (m_targets.empty()) if (m_targets.empty())
return; return;
if (!m_initialized) if (!m_initialized) {
{
m_currentPosition = owner->GetLocalPosition(); m_currentPosition = owner->GetLocalPosition();
m_initialized = true; m_initialized = true;
} }
@ -59,62 +61,59 @@ void PathFollowerComponent::Update(float dt)
Vec2 delta = target - m_currentPosition; Vec2 delta = target - m_currentPosition;
float dist = delta.Length(); float dist = delta.Length();
if (dist < 1.0f) constexpr int m_arrivalRadius = 10;
{
if (m_pathMode == PathMode::Loop) // if we've arrived at this waypoint, advance based on mode
{ if (dist < m_arrivalRadius) {
switch (m_pathMode) {
case PathMode::Loop:
m_currentTarget = (m_currentTarget + 1) % m_targets.size(); m_currentTarget = (m_currentTarget + 1) % m_targets.size();
break;
case 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::PingPong) break;
{
if (m_forward) case PathMode::Stop:
{ if (m_currentTarget + 1 < m_targets.size()) m_currentTarget++;
if (m_currentTarget + 1 < m_targets.size()) else return; // done
m_currentTarget++; break;
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;
} }
return; Vec2 direction = delta / dist;
float cornerFactor = 1.0f;
if (m_currentTarget > 0 && m_currentTarget + 1 < m_targets.size()) {
Vec2 inDir = (m_targets[m_currentTarget] - m_targets[m_currentTarget - 1]).Normalized();
Vec2 outDir = (m_targets[m_currentTarget + 1] - m_targets[m_currentTarget]).Normalized();
float dot = std::clamp(inDir.Dot(outDir), -1.0f, 1.0f);
float angle = std::acos(dot); // 0 → straight, π → Uturn
cornerFactor = 1.0f - (angle / static_cast<float>(PI));
cornerFactor = std::clamp(cornerFactor, 0.0f, 1.0f);
} }
Vec2 direction = delta.Normalized(); // apply easing and speed
float slowdownFactor = 1.0f; float eased = Ease(cornerFactor);
float v = eased * m_speed;
if (m_currentTarget > 0 && m_currentTarget < m_targets.size() - 1) // move and write back
{ m_currentPosition += direction * v * dt;
slowdownFactor = GetCornerSharpness(
m_targets[m_currentTarget - 1],
m_targets[m_currentTarget],
m_targets[m_currentTarget + 1]);
}
float easedSpeed = Ease(slowdownFactor) * m_speed;
m_currentPosition += direction * easedSpeed * dt;
owner->SetLocalPosition(m_currentPosition); owner->SetLocalPosition(m_currentPosition);
} }
void PathFollowerComponent::Save(YAML::Emitter &out) const void PathFollowerComponent::Save(YAML::Emitter &out) const
{ {
out << YAML::BeginMap; out << YAML::BeginMap;

View File

@ -441,7 +441,12 @@ void DrawGizmoForObject(const std::shared_ptr<Object> &obj,
{ {
ImGuizmo::BeginFrame(); ImGuizmo::BeginFrame();
if (!obj || playing) if (!g_engineConfig.settings.draw_gizmos)
{
return;
}
if (!obj || playing )
return; return;
// Model matrix at z = 1 to avoid clipping // Model matrix at z = 1 to avoid clipping
@ -927,6 +932,12 @@ void Engine::Run()
ImGui::EndPopup(); ImGui::EndPopup();
} }
if (ImGui::IsKeyPressed(ImGuiKey_Escape) && selected)
{
selected = nullptr;
}
for (auto &obj : objects) for (auto &obj : objects)
if (obj && !obj->GetParent()) if (obj && !obj->GetParent())
DrawObjectNode(obj); DrawObjectNode(obj);
@ -1174,7 +1185,141 @@ void Engine::Run()
screenMousePos.x < viewportSize.x && screenMousePos.x < viewportSize.x &&
screenMousePos.y < viewportSize.y; screenMousePos.y < viewportSize.y;
if (selected && mouseInWindow) if (g_engineConfig.settings.draw_gizmos && selected)
{
auto follower = selected->GetComponent<PathFollowerComponent>();
auto light = selected->GetComponent<LightComponent>();
if (light)
{
auto *drawList = ImGui::GetWindowDrawList();
ImVec2 winPos = ImGui::GetWindowPos();
ImVec2 winSize = ImGui::GetWindowSize();
auto worldToScreen = [&](const core::types::Vec2 &w)
{
float x = (w.x - cameraPos.x) * cameraZoom + winSize.x * 0.5f;
float y = (w.y - cameraPos.y) * cameraZoom + winSize.y * 0.5f;
return ImVec2(winPos.x + x, winPos.y + y);
};
core::types::Vec2 lightPos = light->GetOwner()->GetWorldPosition();
float radiusWorld = light->GetRadius();
glm::vec3 color = light->GetColor();
ImVec2 center = worldToScreen(lightPos);
float radiusPx = radiusWorld * cameraZoom;
ImU32 col = IM_COL32(
int(color.r * 255),
int(color.g * 255),
int(color.b * 255),
100);
const float thickness = 2.0f;
drawList->AddCircle(center, radiusPx, col, 0, thickness);
drawList->AddLine(
ImVec2(center.x - radiusPx, center.y),
ImVec2(center.x + radiusPx, center.y),
col, thickness);
drawList->AddLine(
ImVec2(center.x, center.y - radiusPx),
ImVec2(center.x, center.y + radiusPx),
col, thickness);
}
if (follower)
{
static int dragIndex = -1;
auto *drawList = ImGui::GetWindowDrawList();
ImVec2 winPos = ImGui::GetWindowPos();
ImVec2 winSize = ImGui::GetWindowSize();
ImVec2 mouse = ImGui::GetIO().MousePos;
auto worldToScreen = [&](const core::types::Vec2 &w)
{
float x = (w.x - cameraPos.x) * cameraZoom + winSize.x * 0.5f;
float y = (w.y - cameraPos.y) * cameraZoom + winSize.y * 0.5f;
return ImVec2(winPos.x + x, winPos.y + y);
};
auto screenToWorld = [&](const ImVec2 &s)
{
float localX = s.x - winPos.x - winSize.x * 0.5f;
float localY = s.y - winPos.y - winSize.y * 0.5f;
return core::types::Vec2(localX / cameraZoom + cameraPos.x,
localY / cameraZoom + cameraPos.y);
};
auto &targets = follower->GetTargets();
const int n = (int)targets.size();
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
dragIndex = -1;
for (int i = 0; i < n; ++i)
{
ImVec2 p = worldToScreen(targets[i]);
float dx = mouse.x - p.x, dy = mouse.y - p.y;
if (dx * dx + dy * dy < 64.0f)
{
dragIndex = i;
break;
}
}
}
if (dragIndex >= 0 && ImGui::IsMouseDown(ImGuiMouseButton_Left))
{
ImVec2 s{mouse.x, mouse.y};
targets[dragIndex] = screenToWorld(s);
}
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
dragIndex = -1;
for (int i = 0; i + 1 < n; ++i)
{
drawList->AddLine(
worldToScreen(targets[i]),
worldToScreen(targets[i + 1]),
IM_COL32(0, 255, 0, 200),
2.0f);
}
if (follower->GetPathMode() == PathMode::Loop && n > 1)
{
drawList->AddLine(
worldToScreen(targets.back()),
worldToScreen(targets.front()),
IM_COL32(0, 255, 0, 200),
2.0f);
}
for (int i = 0; i < n; ++i)
{
auto col = (i == dragIndex)
? IM_COL32(255, 255, 0, 255)
: IM_COL32(255, 0, 0, 200);
drawList->AddCircleFilled(
worldToScreen(targets[i]),
6.0f,
col);
}
drawList->AddCircle(
worldToScreen(follower->GetOwner()->GetWorldPosition()),
6.0f,
IM_COL32(0, 0, 255, 255),
12,
2.0f);
}
}
if (g_engineConfig.settings.draw_gizmos && selected && mouseInWindow)
{ {
auto tilemap = selected->GetComponent<TilemapComponent>(); auto tilemap = selected->GetComponent<TilemapComponent>();
if (tilemap && tilemap->HasSelection()) if (tilemap && tilemap->HasSelection())
@ -1458,6 +1603,8 @@ void Engine::DrawObjectNode(const std::shared_ptr<Object> &obj)
if (!obj) if (!obj)
return; return;
PROFILE_ENGINE_SCOPE("Engine::DrawObjectNode"); PROFILE_ENGINE_SCOPE("Engine::DrawObjectNode");
const bool isSelected = (obj == selected); const bool isSelected = (obj == selected);