From 2b5e2893c5999a2e19bcdd24f00abcbd43109f8a Mon Sep 17 00:00:00 2001 From: Haselnussbomber Date: Mon, 8 Dec 2025 21:25:32 +0100 Subject: [PATCH] Add ImAnim bindings --- .gitmodules | 3 + Dalamud.sln | 21 +- Dalamud/Dalamud.csproj | 1 + .../ImGuiBackend/Dx11Win32Backend.cs | 12 + .../Interface/Internal/DalamudInterface.cs | 12 + external/cimanim/cimanim.cpp | 438 ++++++ external/cimanim/cimanim.h | 443 ++++++ external/cimanim/cimanim.vcxproj | 108 ++ .../Dalamud.Bindings.ImAnim.csproj | 13 + .../Enums/ImAnimAnchorSpace.cs | 24 + .../Enums/ImAnimColorSpace.cs | 29 + .../Enums/ImAnimDirection.cs | 19 + .../Enums/ImAnimEaseStepsMode.cs | 8 + .../Enums/ImAnimEaseType.cs | 70 + .../Enums/ImAnimNoiseType.cs | 24 + .../Enums/ImAnimPolicy.cs | 19 + .../Enums/ImAnimResult.cs | 9 + .../Enums/ImAnimRotationMode.cs | 29 + .../Enums/ImAnimTextPathAlign.cs | 19 + .../Enums/ImAnimTextStaggerEffect.cs | 59 + .../Enums/ImAnimVariationMode.cs | 44 + .../Enums/ImAnimWaveType.cs | 24 + imgui/Dalamud.Bindings.ImAnim/ImAnim.cs | 1236 +++++++++++++++++ imgui/Dalamud.Bindings.ImAnim/ImAnimNative.cs | 809 +++++++++++ .../Structs/ImAnimClip.cs | 338 +++++ .../Structs/ImAnimDragFeedback.cs | 15 + .../Structs/ImAnimDragOpts.cs | 17 + .../Structs/ImAnimEaseDesc.cs | 13 + .../Structs/ImAnimEasePerAxis.cs | 28 + .../Structs/ImAnimGradient.cs | 13 + .../Structs/ImAnimInstance.cs | 155 +++ .../Structs/ImAnimMorphOpts.cs | 13 + .../Structs/ImAnimNoiseOpts.cs | 28 + .../Structs/ImAnimSpringParams.cs | 12 + .../Structs/ImAnimTextPathOpts.cs | 21 + .../Structs/ImAnimTextStaggerOpts.cs | 32 + .../Structs/ImAnimTransform.cs | 12 + .../Structs/ImAnimVariationColor.cs | 170 +++ .../Structs/ImAnimVariationFloat.cs | 103 ++ .../Structs/ImAnimVariationInt.cs | 92 ++ .../Structs/ImAnimVariationVec2.cs | 149 ++ .../Structs/ImAnimVariationVec4.cs | 170 +++ lib/ImAnim | 1 + 43 files changed, 4852 insertions(+), 3 deletions(-) create mode 100644 external/cimanim/cimanim.cpp create mode 100644 external/cimanim/cimanim.h create mode 100644 external/cimanim/cimanim.vcxproj create mode 100644 imgui/Dalamud.Bindings.ImAnim/Dalamud.Bindings.ImAnim.csproj create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimAnchorSpace.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimColorSpace.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimDirection.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseStepsMode.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseType.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimNoiseType.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimPolicy.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimResult.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimRotationMode.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextPathAlign.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextStaggerEffect.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimVariationMode.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimWaveType.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/ImAnim.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/ImAnimNative.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimClip.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragFeedback.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragOpts.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEaseDesc.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEasePerAxis.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimGradient.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimInstance.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimMorphOpts.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimNoiseOpts.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimSpringParams.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextPathOpts.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextStaggerOpts.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTransform.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationColor.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationFloat.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationInt.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec2.cs create mode 100644 imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec4.cs create mode 160000 lib/ImAnim diff --git a/.gitmodules b/.gitmodules index 0d12df2b8..9bb1e86ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "lib/Lumina.Excel"] path = lib/Lumina.Excel url = https://github.com/NotAdam/Lumina.Excel.git +[submodule "lib/ImAnim"] + path = lib/ImAnim + url = https://github.com/soufianekhiat/ImAnim.git diff --git a/Dalamud.sln b/Dalamud.sln index ee3c75b25..ec8894e76 100644 --- a/Dalamud.sln +++ b/Dalamud.sln @@ -1,6 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.1.32319.34 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11222.15 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CEF7D22B-CB85-400E-BD64-349A30E3C097}" ProjectSection(SolutionItems) = preProject @@ -59,12 +60,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cimplot", "external\cimplot EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cimguizmo", "external\cimguizmo\cimguizmo.vcxproj", "{F258347D-31BE-4605-98CE-40E43BDF6F9D}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cimanim", "external\cimanim\cimanim.vcxproj", "{9E65E2A1-1337-4180-87D9-1234567890AB}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.Bindings.ImGui", "imgui\Dalamud.Bindings.ImGui\Dalamud.Bindings.ImGui.csproj", "{B0AA8737-33A3-4766-8CBE-A48F2EF283BA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.Bindings.ImGuizmo", "imgui\Dalamud.Bindings.ImGuizmo\Dalamud.Bindings.ImGuizmo.csproj", "{5E6EDD75-AE95-43A6-9D67-95B840EB4B71}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.Bindings.ImPlot", "imgui\Dalamud.Bindings.ImPlot\Dalamud.Bindings.ImPlot.csproj", "{9C70BD06-D52C-425E-9C14-5D66BC6046EF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.Bindings.ImAnim", "imgui\Dalamud.Bindings.ImAnim\Dalamud.Bindings.ImAnim.csproj", "{16908026-23E1-41F4-85A4-C0096EC5FA24}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bindings", "Bindings", "{A217B3DF-607A-4EFB-B107-3C4809348043}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StandaloneImGuiTestbed", "imgui\StandaloneImGuiTestbed\StandaloneImGuiTestbed.csproj", "{4702A911-2513-478C-A434-2776393FDE77}" @@ -147,6 +152,10 @@ Global {F258347D-31BE-4605-98CE-40E43BDF6F9D}.Debug|Any CPU.Build.0 = Debug|x64 {F258347D-31BE-4605-98CE-40E43BDF6F9D}.Release|Any CPU.ActiveCfg = Release|x64 {F258347D-31BE-4605-98CE-40E43BDF6F9D}.Release|Any CPU.Build.0 = Release|x64 + {9E65E2A1-1337-4180-87D9-1234567890AB}.Debug|Any CPU.ActiveCfg = Debug|x64 + {9E65E2A1-1337-4180-87D9-1234567890AB}.Debug|Any CPU.Build.0 = Debug|x64 + {9E65E2A1-1337-4180-87D9-1234567890AB}.Release|Any CPU.ActiveCfg = Release|x64 + {9E65E2A1-1337-4180-87D9-1234567890AB}.Release|Any CPU.Build.0 = Release|x64 {B0AA8737-33A3-4766-8CBE-A48F2EF283BA}.Debug|Any CPU.ActiveCfg = Debug|x64 {B0AA8737-33A3-4766-8CBE-A48F2EF283BA}.Debug|Any CPU.Build.0 = Debug|x64 {B0AA8737-33A3-4766-8CBE-A48F2EF283BA}.Release|Any CPU.ActiveCfg = Release|x64 @@ -159,6 +168,10 @@ Global {9C70BD06-D52C-425E-9C14-5D66BC6046EF}.Debug|Any CPU.Build.0 = Debug|x64 {9C70BD06-D52C-425E-9C14-5D66BC6046EF}.Release|Any CPU.ActiveCfg = Release|x64 {9C70BD06-D52C-425E-9C14-5D66BC6046EF}.Release|Any CPU.Build.0 = Release|x64 + {16908026-23E1-41F4-85A4-C0096EC5FA24}.Debug|Any CPU.ActiveCfg = Debug|x64 + {16908026-23E1-41F4-85A4-C0096EC5FA24}.Debug|Any CPU.Build.0 = Debug|x64 + {16908026-23E1-41F4-85A4-C0096EC5FA24}.Release|Any CPU.ActiveCfg = Release|x64 + {16908026-23E1-41F4-85A4-C0096EC5FA24}.Release|Any CPU.Build.0 = Release|x64 {4702A911-2513-478C-A434-2776393FDE77}.Debug|Any CPU.ActiveCfg = Debug|x64 {4702A911-2513-478C-A434-2776393FDE77}.Debug|Any CPU.Build.0 = Debug|x64 {4702A911-2513-478C-A434-2776393FDE77}.Release|Any CPU.ActiveCfg = Release|x64 @@ -191,9 +204,11 @@ Global {8BBACF2D-7AB8-4610-A115-0E363D35C291} = {E15BDA6D-E881-4482-94BA-BE5527E917FF} {76CAA246-C405-4A8C-B0AE-F4A0EF3D4E16} = {DBE5345E-6594-4A59-B183-1C3D5592269D} {F258347D-31BE-4605-98CE-40E43BDF6F9D} = {DBE5345E-6594-4A59-B183-1C3D5592269D} + {9E65E2A1-1337-4180-87D9-1234567890AB} = {DBE5345E-6594-4A59-B183-1C3D5592269D} {B0AA8737-33A3-4766-8CBE-A48F2EF283BA} = {A217B3DF-607A-4EFB-B107-3C4809348043} {5E6EDD75-AE95-43A6-9D67-95B840EB4B71} = {A217B3DF-607A-4EFB-B107-3C4809348043} {9C70BD06-D52C-425E-9C14-5D66BC6046EF} = {A217B3DF-607A-4EFB-B107-3C4809348043} + {16908026-23E1-41F4-85A4-C0096EC5FA24} = {A217B3DF-607A-4EFB-B107-3C4809348043} {4702A911-2513-478C-A434-2776393FDE77} = {A217B3DF-607A-4EFB-B107-3C4809348043} {66753AC7-0029-4373-9CC4-7760B1F46141} = {A217B3DF-607A-4EFB-B107-3C4809348043} {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {E15BDA6D-E881-4482-94BA-BE5527E917FF} diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 7ea4f2caa..4f2c98599 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -103,6 +103,7 @@ + diff --git a/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs b/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs index ea609828d..2208edf14 100644 --- a/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs +++ b/Dalamud/Interface/ImGuiBackend/Dx11Win32Backend.cs @@ -5,6 +5,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Dalamud.Bindings.ImAnim; using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGuizmo; using Dalamud.Bindings.ImPlot; @@ -40,6 +41,7 @@ internal sealed unsafe class Dx11Win32Backend : IWin32Backend private int targetWidth; private int targetHeight; + private int gcCounter; /// /// Initializes a new instance of the class. @@ -75,6 +77,7 @@ internal sealed unsafe class Dx11Win32Backend : IWin32Backend ImGuizmo.SetImGuiContext(ctx); ImPlot.SetImGuiContext(ctx); ImPlot.CreateContext(); + ImAnim.SetImGuiContext(ctx); ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.DockingEnable | ImGuiConfigFlags.ViewportsEnable; @@ -168,6 +171,15 @@ internal sealed unsafe class Dx11Win32Backend : IWin32Backend ImGui.NewFrame(); ImGuizmo.BeginFrame(); + ImAnim.UpdateBeginFrame(); + ImAnim.ClipUpdate(ImGui.GetIO().DeltaTime); + + if (++this.gcCounter >= 300) + { + this.gcCounter = 0; + ImAnim.Gc(600); // Remove tweens inactive for 600+ frames + ImAnim.ClipGc(600); // Remove clip instances inactive for 600+ frames + } this.BuildUi?.Invoke(); diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index bf55a5486..dc0545ad6 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -7,6 +7,8 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using CheapLoc; + +using Dalamud.Bindings.ImAnim; using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImPlot; using Dalamud.Configuration.Internal; @@ -88,6 +90,8 @@ internal class DalamudInterface : IInternalDisposableService private bool isImGuiDrawDemoWindow = false; private bool isImPlotDrawDemoWindow = false; + private bool isImAnimDrawDemoWindow = false; + private bool isImAnimUnifiedInspector = false; private bool isImGuiTestWindowsInMonospace = false; private bool isImGuiDrawMetricsWindow = false; @@ -576,6 +580,12 @@ internal class DalamudInterface : IInternalDisposableService if (this.isImPlotDrawDemoWindow) ImPlot.ShowDemoWindow(ref this.isImPlotDrawDemoWindow); + if (this.isImAnimDrawDemoWindow) + ImAnim.DemoWindow(); + + if (this.isImAnimUnifiedInspector) + ImAnim.ShowUnifiedInspector(ref this.isImAnimUnifiedInspector); + if (this.isImGuiDrawMetricsWindow) ImGui.ShowMetricsWindow(ref this.isImGuiDrawMetricsWindow); @@ -874,6 +884,8 @@ internal class DalamudInterface : IInternalDisposableService ImGui.MenuItem("Use Monospace font for following windows"u8, (byte*)null, ref this.isImGuiTestWindowsInMonospace); ImGui.MenuItem("Draw ImGui demo"u8, (byte*)null, ref this.isImGuiDrawDemoWindow); ImGui.MenuItem("Draw ImPlot demo"u8, (byte*)null, ref this.isImPlotDrawDemoWindow); + ImGui.MenuItem("Draw ImAnim demo"u8, (byte*)null, ref this.isImAnimDrawDemoWindow); + ImGui.MenuItem("Draw ImAnim Inspector"u8, (byte*)null, ref this.isImAnimUnifiedInspector); ImGui.MenuItem("Draw metrics"u8, (byte*)null, ref this.isImGuiDrawMetricsWindow); ImGui.Separator(); diff --git a/external/cimanim/cimanim.cpp b/external/cimanim/cimanim.cpp new file mode 100644 index 000000000..5d1ae7920 --- /dev/null +++ b/external/cimanim/cimanim.cpp @@ -0,0 +1,438 @@ +#include "cimanim.h" + +// ---------------------------------------------------- +// Public API declarations +// ---------------------------------------------------- + +CIMGUI_API void c_iam_set_imgui_context(ImGuiContext* context) { ImGui::SetCurrentContext(context); } +CIMGUI_API void c_iam_demo_window() { ImAnimDemoWindow(); } + +// Frame management +CIMGUI_API void c_iam_update_begin_frame() { iam_update_begin_frame(); } +CIMGUI_API void c_iam_gc(unsigned int max_age_frames) { iam_gc(max_age_frames); } +CIMGUI_API void c_iam_reserve(int cap_float, int cap_vec2, int cap_vec4, int cap_int, int cap_color) { iam_reserve(cap_float, cap_vec2, cap_vec4, cap_int, cap_color); } +CIMGUI_API void c_iam_set_ease_lut_samples(int count) { iam_set_ease_lut_samples(count); } + +// Global time scale (for slow-motion / fast-forward debugging) +CIMGUI_API void c_iam_set_global_time_scale(float scale) { iam_set_global_time_scale(scale); } +CIMGUI_API float c_iam_get_global_time_scale() { return iam_get_global_time_scale(); } + +// Lazy Initialization - defer channel creation until animation is needed +CIMGUI_API void c_iam_set_lazy_init(bool enable) { iam_set_lazy_init(enable); } +CIMGUI_API bool c_iam_is_lazy_init_enabled() { return iam_is_lazy_init_enabled(); } + +CIMGUI_API void c_iam_register_custom_ease(int slot, iam_ease_fn fn) { iam_register_custom_ease(slot, fn); } +CIMGUI_API void c_iam_get_custom_ease(iam_ease_fn* pOut, int slot) { *pOut = iam_get_custom_ease(slot); } + +// Debug UI +CIMGUI_API void c_iam_show_unified_inspector(bool* p_open) { iam_show_unified_inspector(p_open); } + +// Performance Profiler +CIMGUI_API void c_iam_profiler_enable(bool enable) { iam_profiler_enable(enable); } +CIMGUI_API bool c_iam_profiler_is_enabled() { return iam_profiler_is_enabled(); } +CIMGUI_API void c_iam_profiler_begin_frame() { iam_profiler_begin_frame(); } +CIMGUI_API void c_iam_profiler_end_frame() { iam_profiler_end_frame(); } +CIMGUI_API void c_iam_profiler_begin(const char* name) { iam_profiler_begin(name); } +CIMGUI_API void c_iam_profiler_end() { iam_profiler_end(); } + +// Drag Feedback - animated feedback for drag operations +CIMGUI_API void c_iam_drag_begin(iam_drag_feedback* pOut, ImGuiID id, ImVec2* pos) { *pOut = iam_drag_begin(id, *pos); } +CIMGUI_API void c_iam_drag_update(iam_drag_feedback* pOut, ImGuiID id, ImVec2* pos, float dt) { *pOut = iam_drag_update(id, *pos, dt); } +CIMGUI_API void c_iam_drag_release(iam_drag_feedback* pOut, ImGuiID id, ImVec2* pos, iam_drag_opts* opts, float dt) { *pOut = iam_drag_release(id, *pos, opts ? *opts : iam_drag_opts(), dt); } +CIMGUI_API void c_iam_drag_cancel(ImGuiID id) { iam_drag_cancel(id); } + +// Oscillators - continuous periodic animations +CIMGUI_API float c_iam_oscillate(ImGuiID id, float amplitude, float frequency, int wave_type, float phase, float dt) { return iam_oscillate(id, amplitude, frequency, wave_type, phase, dt); } +CIMGUI_API int c_iam_oscillate_int(ImGuiID id, int amplitude, float frequency, int wave_type, float phase, float dt) { return iam_oscillate_int(id, amplitude, frequency, wave_type, phase, dt); } +CIMGUI_API void c_iam_oscillate_vec2(ImVec2* pOut, ImGuiID id, ImVec2* amplitude, ImVec2* frequency, int wave_type, ImVec2* phase, float dt) { *pOut = iam_oscillate_vec2(id, *amplitude, *frequency, wave_type, *phase, dt); } +CIMGUI_API void c_iam_oscillate_vec4(ImVec4* pOut, ImGuiID id, ImVec4* amplitude, ImVec4* frequency, int wave_type, ImVec4* phase, float dt) { *pOut = iam_oscillate_vec4(id, *amplitude, *frequency, wave_type, *phase, dt); } +CIMGUI_API void c_iam_oscillate_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float frequency, int wave_type, float phase, int color_space, float dt) { *pOut = iam_oscillate_color(id, *base_color, *amplitude, frequency, wave_type, phase, color_space, dt); } + +// Shake/Wiggle - procedural noise animations +CIMGUI_API float c_iam_shake(ImGuiID id, float intensity, float frequency, float decay_time, float dt) { return iam_shake(id, intensity, frequency, decay_time, dt); } +CIMGUI_API int c_iam_shake_int(ImGuiID id, int intensity, float frequency, float decay_time, float dt) { return iam_shake_int(id, intensity, frequency, decay_time, dt); } +CIMGUI_API void c_iam_shake_vec2(ImVec2* pOut, ImGuiID id, ImVec2* intensity, float frequency, float decay_time, float dt) { *pOut = iam_shake_vec2(id, *intensity, frequency, decay_time, dt); } +CIMGUI_API void c_iam_shake_vec4(ImVec4* pOut, ImGuiID id, ImVec4* intensity, float frequency, float decay_time, float dt) { *pOut = iam_shake_vec4(id, *intensity, frequency, decay_time, dt); } +CIMGUI_API void c_iam_shake_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* intensity, float frequency, float decay_time, int color_space, float dt) { *pOut = iam_shake_color(id, *base_color, *intensity, frequency, decay_time, color_space, dt); } +CIMGUI_API float c_iam_wiggle(ImGuiID id, float amplitude, float frequency, float dt) { return iam_wiggle(id, amplitude, frequency, dt); } +CIMGUI_API int c_iam_wiggle_int(ImGuiID id, int amplitude, float frequency, float dt) { return iam_wiggle_int(id, amplitude, frequency, dt); } +CIMGUI_API void c_iam_wiggle_vec2(ImVec2* pOut, ImGuiID id, ImVec2* amplitude, float frequency, float dt) { *pOut = iam_wiggle_vec2(id, *amplitude, frequency, dt); } +CIMGUI_API void c_iam_wiggle_vec4(ImVec4* pOut, ImGuiID id, ImVec4* amplitude, float frequency, float dt) { *pOut = iam_wiggle_vec4(id, *amplitude, frequency, dt); } +CIMGUI_API void c_iam_wiggle_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float frequency, int color_space, float dt) { *pOut = iam_wiggle_color(id, *base_color, *amplitude, frequency, color_space, dt); } +CIMGUI_API void c_iam_trigger_shake(ImGuiID id) { iam_trigger_shake(id); } + +// Easing evaluation +CIMGUI_API float c_iam_eval_preset(int type, float t) { return iam_eval_preset(type, t); } + +// Tween API - smoothly interpolate values over time +CIMGUI_API float c_iam_tween_float(ImGuiID id, ImGuiID channel_id, float target, float dur, iam_ease_desc* ez, int policy, float dt) { return iam_tween_float(id, channel_id, target, dur, *ez, policy, dt); } +CIMGUI_API void c_iam_tween_vec2(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImVec2* target, float dur, iam_ease_desc* ez, int policy, float dt) { *pOut = iam_tween_vec2(id, channel_id, *target, dur, *ez, policy, dt); } +CIMGUI_API void c_iam_tween_vec4(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target, float dur, iam_ease_desc* ez, int policy, float dt) { *pOut = iam_tween_vec4(id, channel_id, *target, dur, *ez, policy, dt); } +CIMGUI_API int c_iam_tween_int(ImGuiID id, ImGuiID channel_id, int target, float dur, iam_ease_desc* ez, int policy, float dt) { return iam_tween_int(id, channel_id, target, dur, *ez, policy, dt); } +CIMGUI_API void c_iam_tween_color(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target_srgb, float dur, iam_ease_desc* ez, int policy, int color_space, float dt) { *pOut = iam_tween_color(id, channel_id, *target_srgb, dur, *ez, policy, color_space, dt); } + +// Resize-friendly helpers +CIMGUI_API void c_iam_anchor_size(ImVec2* pOut, int space) { *pOut = iam_anchor_size(space); } + +// Relative target tweens (percent of anchor + pixel offset) - survive window resizes +CIMGUI_API float c_iam_tween_float_rel(ImGuiID id, ImGuiID channel_id, float percent, float px_bias, float dur, iam_ease_desc* ez, int policy, int anchor_space, int axis, float dt) { return iam_tween_float_rel(id, channel_id, percent, px_bias, dur, *ez, policy, anchor_space, axis, dt); } +CIMGUI_API void c_iam_tween_vec2_rel(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImVec2* percent, ImVec2* px_bias, float dur, iam_ease_desc* ez, int policy, int anchor_space, float dt) { *pOut = iam_tween_vec2_rel(id, channel_id, *percent, *px_bias, dur, *ez, policy, anchor_space, dt); } +CIMGUI_API void c_iam_tween_vec4_rel(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* percent, ImVec4* px_bias, float dur, iam_ease_desc* ez, int policy, int anchor_space, float dt) { *pOut = iam_tween_vec4_rel(id, channel_id, *percent, *px_bias, dur, *ez, policy, anchor_space, dt); } +CIMGUI_API void c_iam_tween_color_rel(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* percent, ImVec4* px_bias, float dur, iam_ease_desc* ez, int policy, int color_space, int anchor_space, float dt) { *pOut = iam_tween_color_rel(id, channel_id, *percent, *px_bias, dur, *ez, policy, color_space, anchor_space, dt); } + +// Rebase functions - change target of in-progress animation without restarting +CIMGUI_API void c_iam_rebase_float(ImGuiID id, ImGuiID channel_id, float new_target, float dt) { iam_rebase_float(id, channel_id, new_target, dt); } +CIMGUI_API void c_iam_rebase_vec2(ImGuiID id, ImGuiID channel_id, ImVec2* new_target, float dt) { iam_rebase_vec2(id, channel_id, *new_target, dt); } +CIMGUI_API void c_iam_rebase_vec4(ImGuiID id, ImGuiID channel_id, ImVec4* new_target, float dt) { iam_rebase_vec4(id, channel_id, *new_target, dt); } +CIMGUI_API void c_iam_rebase_color(ImGuiID id, ImGuiID channel_id, ImVec4* new_target, float dt) { iam_rebase_color(id, channel_id, *new_target, dt); } +CIMGUI_API void c_iam_rebase_int(ImGuiID id, ImGuiID channel_id, int new_target, float dt) { iam_rebase_int(id, channel_id, new_target, dt); } + +// Resolved tweens - target computed dynamically by callback each frame +CIMGUI_API float c_iam_tween_float_resolved(ImGuiID id, ImGuiID channel_id, iam_float_resolver fn, void* user, float dur, iam_ease_desc* ez, int policy, float dt) { return iam_tween_float_resolved(id, channel_id, fn, user, dur, *ez, policy, dt); } +CIMGUI_API void c_iam_tween_vec2_resolved(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, iam_vec2_resolver fn, void* user, float dur, iam_ease_desc* ez, int policy, float dt) { *pOut = iam_tween_vec2_resolved(id, channel_id, fn, user, dur, *ez, policy, dt); } +CIMGUI_API void c_iam_tween_vec4_resolved(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, iam_vec4_resolver fn, void* user, float dur, iam_ease_desc* ez, int policy, float dt) { *pOut = iam_tween_vec4_resolved(id, channel_id, fn, user, dur, *ez, policy, dt); } +CIMGUI_API void c_iam_tween_color_resolved(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, iam_vec4_resolver fn, void* user, float dur, iam_ease_desc* ez, int policy, int color_space, float dt) { *pOut = iam_tween_color_resolved(id, channel_id, fn, user, dur, *ez, policy, color_space, dt); } +CIMGUI_API int c_iam_tween_int_resolved(ImGuiID id, ImGuiID channel_id, iam_int_resolver fn, void* user, float dur, iam_ease_desc* ez, int policy, float dt) { return iam_tween_int_resolved(id, channel_id, fn, user, dur, *ez, policy, dt); } + +// Color blending utility +CIMGUI_API void c_iam_get_blended_color(ImVec4* pOut, ImVec4* a_srgb, ImVec4* b_srgb, float t, int color_space) { *pOut = iam_get_blended_color(*a_srgb, *b_srgb, t, color_space); } + + +// ---------------------------------------------------- +// Convenience shorthands for common easings +// ---------------------------------------------------- + +CIMGUI_API void c_iam_ease_preset(iam_ease_desc* pOut, int type) { *pOut = iam_ease_preset(type); } +CIMGUI_API void c_iam_ease_bezier(iam_ease_desc* pOut, float x1, float y1, float x2, float y2) { *pOut = iam_ease_bezier(x1, y1, x2, y2); } +CIMGUI_API void c_iam_ease_steps_desc(iam_ease_desc* pOut, int steps, int mode) { *pOut = iam_ease_steps_desc(steps, mode); } +CIMGUI_API void c_iam_ease_back(iam_ease_desc* pOut, float overshoot) { *pOut = iam_ease_back(overshoot); } +CIMGUI_API void c_iam_ease_elastic(iam_ease_desc* pOut, float amplitude, float period) { *pOut = iam_ease_elastic(amplitude, period); } +CIMGUI_API void c_iam_ease_spring_desc(iam_ease_desc* pOut, float mass, float stiffness, float damping, float v0) { *pOut = iam_ease_spring_desc(mass, stiffness, damping, v0); } +CIMGUI_API void c_iam_ease_custom_fn(iam_ease_desc* pOut, int slot) { *pOut = iam_ease_custom_fn(slot); } + +// Scroll animation - smooth scrolling for ImGui windows +CIMGUI_API void c_iam_scroll_to_y(float target_y, float duration, iam_ease_desc* ez) { iam_scroll_to_y(target_y, duration, *ez); } +CIMGUI_API void c_iam_scroll_to_x(float target_x, float duration, iam_ease_desc* ez) { iam_scroll_to_x(target_x, duration, *ez); } +CIMGUI_API void c_iam_scroll_to_top(float duration, iam_ease_desc* ez) { iam_scroll_to_top(duration, *ez); } +CIMGUI_API void c_iam_scroll_to_bottom(float duration, iam_ease_desc* ez) { iam_scroll_to_bottom(duration, *ez); } + + +// ---------------------------------------------------- +// Per-axis easing - different easing per component +// ---------------------------------------------------- + +// Tween with per-axis easing - each component uses its own easing curve +CIMGUI_API void c_iam_tween_vec2_per_axis(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImVec2* target, float dur, iam_ease_per_axis* ez, int policy, float dt) { *pOut = iam_tween_vec2_per_axis(id, channel_id, *target, dur, ez ? *ez : iam_ease_per_axis(), policy, dt); } +CIMGUI_API void c_iam_tween_vec4_per_axis(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target, float dur, iam_ease_per_axis* ez, int policy, float dt) { *pOut = iam_tween_vec4_per_axis(id, channel_id, *target, dur, ez ? *ez : iam_ease_per_axis(), policy, dt); } +CIMGUI_API void c_iam_tween_color_per_axis(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target_srgb, float dur, iam_ease_per_axis* ez, int policy, int color_space, float dt) { *pOut = iam_tween_color_per_axis(id, channel_id, *target_srgb, dur, ez ? *ez : iam_ease_per_axis(), policy, color_space, dt); } + + +// ---------------------------------------------------- +// Motion Paths - animate along curves and splines +// ---------------------------------------------------- + +// Single-curve evaluation functions (stateless, for direct use) +CIMGUI_API void c_iam_bezier_quadratic(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, float t) { *pOut = iam_bezier_quadratic(*p0, *p1, *p2, t); } +CIMGUI_API void c_iam_bezier_cubic(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t) { *pOut = iam_bezier_cubic(*p0, *p1, *p2, *p3, t); } +CIMGUI_API void c_iam_catmull_rom(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t, float tension) { *pOut = iam_catmull_rom(*p0, *p1, *p2, *p3, t, tension); } + +// Derivatives (for tangent/velocity) +CIMGUI_API void c_iam_bezier_quadratic_deriv(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, float t) { *pOut = iam_bezier_quadratic_deriv(*p0, *p1, *p2, t); } +CIMGUI_API void c_iam_bezier_cubic_deriv(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t) { *pOut = iam_bezier_cubic_deriv(*p0, *p1, *p2, *p3, t); } +CIMGUI_API void c_iam_catmull_rom_deriv(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t, float tension) { *pOut = iam_catmull_rom_deriv(*p0, *p1, *p2, *p3, t, tension); } + +// Query path info +CIMGUI_API bool c_iam_path_exists(ImGuiID path_id) { return iam_path_exists(path_id); } +CIMGUI_API float c_iam_path_length(ImGuiID path_id) { return iam_path_length(path_id); } +CIMGUI_API void c_iam_path_evaluate(ImVec2* pOut, ImGuiID path_id, float t) { *pOut = iam_path_evaluate(path_id, t); } +CIMGUI_API void c_iam_path_tangent(ImVec2* pOut, ImGuiID path_id, float t) { *pOut = iam_path_tangent(path_id, t); } +CIMGUI_API float c_iam_path_angle(ImGuiID path_id, float t) { return iam_path_angle(path_id, t); } + +// Tween along a path +CIMGUI_API void c_iam_tween_path(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImGuiID path_id, float dur, iam_ease_desc* ez, int policy, float dt) { *pOut = iam_tween_path(id, channel_id, path_id, dur, *ez, policy, dt); } +CIMGUI_API float c_iam_tween_path_angle(ImGuiID id, ImGuiID channel_id, ImGuiID path_id, float dur, iam_ease_desc* ez, int policy, float dt) { return iam_tween_path_angle(id, channel_id, path_id, dur, *ez, policy, dt); } + + +// ---------------------------------------------------- +// Arc-length parameterization (for constant-speed animation) +// ---------------------------------------------------- + +// Build arc-length lookup table for a path (call once per path, improves accuracy) +CIMGUI_API void c_iam_path_build_arc_lut(ImGuiID path_id, int subdivisions) { iam_path_build_arc_lut(path_id, subdivisions); } +CIMGUI_API bool c_iam_path_has_arc_lut(ImGuiID path_id) { return iam_path_has_arc_lut(path_id); } + +// Distance-based path evaluation (uses arc-length LUT for constant speed) +CIMGUI_API float c_iam_path_distance_to_t(ImGuiID path_id, float distance) { return iam_path_distance_to_t(path_id, distance); } +CIMGUI_API void c_iam_path_evaluate_at_distance(ImVec2* pOut, ImGuiID path_id, float distance) { *pOut = iam_path_evaluate_at_distance(path_id, distance); } +CIMGUI_API float c_iam_path_angle_at_distance(ImGuiID path_id, float distance) { return iam_path_angle_at_distance(path_id, distance); } +CIMGUI_API void c_iam_path_tangent_at_distance(ImVec2* pOut, ImGuiID path_id, float distance) { *pOut = iam_path_tangent_at_distance(path_id, distance); } + + +// ---------------------------------------------------- +// Path Morphing - interpolate between two paths +// ---------------------------------------------------- + +// Evaluate morphed path at parameter t [0,1] with blend factor [0,1] +// path_a at blend=0, path_b at blend=1 +// Paths can have different numbers of segments - they are resampled to match +CIMGUI_API void c_iam_path_morph(ImVec2* pOut, ImGuiID path_a, ImGuiID path_b, float t, float blend, iam_morph_opts* opts) { *pOut = iam_path_morph(path_a, path_b, t, blend, opts ? *opts : iam_morph_opts()); } + +// Get tangent of morphed path +CIMGUI_API void c_iam_path_morph_tangent(ImVec2* pOut, ImGuiID path_a, ImGuiID path_b, float t, float blend, iam_morph_opts* opts) { *pOut = iam_path_morph_tangent(path_a, path_b, t, blend, opts ? *opts : iam_morph_opts()); } + +// Get angle (radians) of morphed path +CIMGUI_API float c_iam_path_morph_angle(ImGuiID path_a, ImGuiID path_b, float t, float blend, iam_morph_opts* opts) { return iam_path_morph_angle(path_a, path_b, t, blend, opts ? *opts : iam_morph_opts()); } + +// Tween along a morphing path - animates both position along path AND the morph blend +CIMGUI_API void c_iam_tween_path_morph(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImGuiID path_a, ImGuiID path_b, float target_blend, float dur, iam_ease_desc* path_ease, iam_ease_desc* morph_ease, int policy, float dt, iam_morph_opts* opts) { + *pOut = iam_tween_path_morph(id, channel_id, path_a, path_b, target_blend, dur, *path_ease, *morph_ease, policy, dt, opts ? *opts : iam_morph_opts()); +} + +// Get current morph blend value from a tween (for querying state) +CIMGUI_API float c_iam_get_morph_blend(ImGuiID id, ImGuiID channel_id) { return iam_get_morph_blend(id, channel_id); } + + +// ---------------------------------------------------- +// Text along motion paths +// ---------------------------------------------------- + +// Render text along a path (static - no animation) +CIMGUI_API void c_iam_text_path(ImGuiID path_id, const char* text, iam_text_path_opts* opts) { iam_text_path(path_id, text, opts ? *opts : iam_text_path_opts()); } + +// Animated text along path (characters appear progressively) +CIMGUI_API void c_iam_text_path_animated(ImGuiID path_id, const char* text, float progress, iam_text_path_opts* opts) { return iam_text_path_animated(path_id, text, progress, opts ? *opts : iam_text_path_opts()); } + +// Helper: Get text width for path layout calculations +CIMGUI_API float c_iam_text_path_width(const char* text, iam_text_path_opts* opts) { return iam_text_path_width(text, opts ? *opts : iam_text_path_opts()); } + + +// ---------------------------------------------------- +// Quad transform helpers (for advanced custom rendering) +// ---------------------------------------------------- + +// Transform a quad (4 vertices) by rotation and translation +CIMGUI_API void c_iam_transform_quad(ImVec2* quad, ImVec2* center, float angle_rad, ImVec2* translation) { iam_transform_quad(quad, *center, angle_rad, *translation); } + +// Create a rotated quad for a glyph at a position on the path +CIMGUI_API void c_iam_make_glyph_quad(ImVec2* quad, ImVec2* pos, float angle_rad, float glyph_width, float glyph_height, float baseline_offset) { iam_make_glyph_quad(quad, *pos, angle_rad, glyph_width, glyph_height, baseline_offset); } + + +// ---------------------------------------------------- +// Text Stagger - per-character animation effects +// ---------------------------------------------------- + +// Render text with per-character stagger animation +CIMGUI_API void c_iam_text_stagger(ImGuiID id, const char* text, float progress, iam_text_stagger_opts* opts) { iam_text_stagger(id, text, progress, opts ? *opts : iam_text_stagger_opts()); } + +// Get text width for layout calculations +CIMGUI_API float c_iam_text_stagger_width(const char* text, iam_text_stagger_opts* opts) { return iam_text_stagger_width(text, opts ? *opts : iam_text_stagger_opts()); } + +// Get total animation duration for text (accounts for stagger delays) +CIMGUI_API float c_iam_text_stagger_duration(const char* text, iam_text_stagger_opts* opts) { return iam_text_stagger_duration(text, opts ? *opts : iam_text_stagger_opts()); } + + +// ---------------------------------------------------- +// Noise Channels - Perlin/Simplex noise for organic movement +// ---------------------------------------------------- + +// Sample noise at a point (returns value in [-1, 1]) +CIMGUI_API float c_iam_noise_2d(float x, float y, iam_noise_opts* opts) { return iam_noise_2d(x, y, opts ? *opts : iam_noise_opts()); } +CIMGUI_API float c_iam_noise_3d(float x, float y, float z, iam_noise_opts* opts) { return iam_noise_3d(x, y, z, opts ? *opts : iam_noise_opts()); } + +// Animated noise channels - continuous noise that evolves over time +CIMGUI_API float c_iam_noise_channel_float(ImGuiID id, float frequency, float amplitude, iam_noise_opts* opts, float dt) { return iam_noise_channel_float(id, frequency, amplitude, opts ? *opts : iam_noise_opts(), dt); } +CIMGUI_API void c_iam_noise_channel_vec2(ImVec2* pOut, ImGuiID id, ImVec2* frequency, ImVec2* amplitude, iam_noise_opts* opts, float dt) { *pOut = iam_noise_channel_vec2(id, *frequency, *amplitude, opts ? *opts : iam_noise_opts(), dt); } +CIMGUI_API void c_iam_noise_channel_vec4(ImVec4* pOut, ImGuiID id, ImVec4* frequency, ImVec4* amplitude, iam_noise_opts* opts, float dt) { *pOut = iam_noise_channel_vec4(id, *frequency, *amplitude, opts ? *opts : iam_noise_opts(), dt); } +CIMGUI_API void c_iam_noise_channel_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float frequency, iam_noise_opts* opts, int color_space, float dt) { *pOut = iam_noise_channel_color(id, *base_color, *amplitude, frequency, opts ? *opts : iam_noise_opts(), color_space, dt); } + +// Convenience: smooth random movement (like wiggle but using noise) +CIMGUI_API float c_iam_smooth_noise_float(ImGuiID id, float amplitude, float speed, float dt) { return iam_smooth_noise_float(id, amplitude, speed, dt); } +CIMGUI_API void c_iam_smooth_noise_vec2(ImVec2* pOut, ImGuiID id, ImVec2* amplitude, float speed, float dt) { *pOut = iam_smooth_noise_vec2(id, *amplitude, speed, dt); } +CIMGUI_API void c_iam_smooth_noise_vec4(ImVec4* pOut, ImGuiID id, ImVec4* amplitude, float speed, float dt) { *pOut = iam_smooth_noise_vec4(id, *amplitude, speed, dt); } +CIMGUI_API void c_iam_smooth_noise_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float speed, int color_space, float dt) { *pOut = iam_smooth_noise_color(id, *base_color, *amplitude, speed, color_space, dt); } + + +// ---------------------------------------------------- +// Style Interpolation - animate between ImGuiStyle themes +// ---------------------------------------------------- + +// Register a named style for interpolation +CIMGUI_API void c_iam_style_register(ImGuiID style_id, ImGuiStyle* style) { iam_style_register(style_id, *style); } +CIMGUI_API void c_iam_style_register_current(ImGuiID style_id) { return iam_style_register_current(style_id); } + +// Blend between two registered styles (result applied to ImGui::GetStyle()) +CIMGUI_API void c_iam_style_blend(ImGuiID style_a, ImGuiID style_b, float t, int color_space) { iam_style_blend(style_a, style_b, t, color_space); } + +// Tween between styles over time +CIMGUI_API void c_iam_style_tween(ImGuiID id, ImGuiID target_style, float duration, iam_ease_desc* ease, int color_space, float dt) { iam_style_tween(id, target_style, duration, ease ? *ease : iam_ease_desc(), color_space, dt); } + +// Get interpolated style without applying +CIMGUI_API void c_iam_style_blend_to(ImGuiID style_a, ImGuiID style_b, float t, ImGuiStyle* out_style, int color_space) { iam_style_blend_to(style_a, style_b, t, out_style, color_space); } + +// Check if a style is registered +CIMGUI_API bool c_iam_style_exists(ImGuiID style_id) { return iam_style_exists(style_id); } + +// Remove a registered style +CIMGUI_API void c_iam_style_unregister(ImGuiID style_id) { iam_style_unregister(style_id); } + + +// ---------------------------------------------------- +// Gradient Interpolation - animate between color gradients +// ---------------------------------------------------- + +// Blend between two gradients +CIMGUI_API void c_iam_gradient_lerp(iam_gradient* pOut, iam_gradient* a, iam_gradient* b, float t, int color_space) { *pOut = iam_gradient_lerp(*a, *b, t, color_space); } + +// Tween between gradients over time +CIMGUI_API void c_iam_tween_gradient(iam_gradient* pOut, ImGuiID id, ImGuiID channel_id, iam_gradient* target, float dur, iam_ease_desc* ez, int policy, int color_space, float dt) { *pOut = iam_tween_gradient(id, channel_id, *target, dur, ez ? *ez : iam_ease_desc(), policy, color_space, dt); } + + +// ---------------------------------------------------- +// Transform Interpolation - animate 2D transforms +// ---------------------------------------------------- + +// Blend between two transforms with rotation interpolation +CIMGUI_API void c_iam_transform_lerp(iam_transform* pOut, iam_transform* a, iam_transform* b, float t, int rotation_mode) { *pOut = iam_transform_lerp(*a, *b, t, rotation_mode); } + +// Tween between transforms over time +CIMGUI_API void c_iam_tween_transform(iam_transform* pOut, ImGuiID id, ImGuiID channel_id, iam_transform* target, float dur, iam_ease_desc* ez, int policy, int rotation_mode, float dt) { *pOut = iam_tween_transform(id, channel_id, *target, dur, ez ? *ez : iam_ease_desc(), policy, rotation_mode, dt); } + +// Decompose a 3x2 matrix into transform components +CIMGUI_API void c_iam_transform_from_matrix(iam_transform* pOut, float m00, float m01, float m10, float m11, float tx, float ty) { *pOut = iam_transform_from_matrix(m00, m01, m10, m11, tx, ty); } + +// Convert transform to 3x2 matrix (row-major: [m00 m01 tx; m10 m11 ty]) +CIMGUI_API void c_iam_transform_to_matrix(iam_transform* t, float* out_matrix) { iam_transform_to_matrix(*t, out_matrix); } + + +// ---------------------------------------------------- +// iam_clip - fluent API for authoring animations +// ---------------------------------------------------- + +CIMGUI_API void c_iam_clip_begin(iam_clip* pOut, ImGuiID clip_id) { *pOut = iam_clip::begin(clip_id); } + +// Add keyframes for different channel types +CIMGUI_API void c_iam_clip_key_float(iam_clip* self, ImGuiID channel, float time, float value, int ease_type, float const* bezier4) { self->key_float(channel, time, value, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_vec2(iam_clip* self, ImGuiID channel, float time, ImVec2* value, int ease_type, float const* bezier4) { self->key_vec2(channel, time, *value, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_vec4(iam_clip* self, ImGuiID channel, float time, ImVec4* value, int ease_type, float const* bezier4) { self->key_vec4(channel, time, *value, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_int(iam_clip* self, ImGuiID channel, float time, int value, int ease_type) { self->key_int(channel, time, value, ease_type); } +CIMGUI_API void c_iam_clip_key_color(iam_clip* self, ImGuiID channel, float time, ImVec4* value, int color_space, int ease_type, float const* bezier4) { self->key_color(channel, time, *value, color_space, ease_type, bezier4); } + +// Keyframes with repeat variation (value changes per loop iteration) +CIMGUI_API void c_iam_clip_key_float_var(iam_clip* self, ImGuiID channel, float time, float value, iam_variation_float* var, int ease_type, float const* bezier4) { self->key_float_var(channel, time, value, *var, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_vec2_var(iam_clip* self, ImGuiID channel, float time, ImVec2* value, iam_variation_vec2* var, int ease_type, float const* bezier4) { self->key_vec2_var(channel, time, *value, *var, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_vec4_var(iam_clip* self, ImGuiID channel, float time, ImVec4* value, iam_variation_vec4* var, int ease_type, float const* bezier4) { self->key_vec4_var(channel, time, *value, *var, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_int_var(iam_clip* self, ImGuiID channel, float time, int value, iam_variation_int* var, int ease_type) { self->key_int_var(channel, time, value, *var, ease_type); } +CIMGUI_API void c_iam_clip_key_color_var(iam_clip* self, ImGuiID channel, float time, ImVec4* value, iam_variation_color* var, int color_space, int ease_type, float const* bezier4) { self->key_color_var(channel, time, *value, *var, color_space, ease_type, bezier4); } + +// Spring-based keyframe (float only) +CIMGUI_API void c_iam_clip_key_float_spring(iam_clip* self, ImGuiID channel, float time, float target, iam_spring_params* spring) { self->key_float_spring(channel, time, target, *spring); } + +// Anchor-relative keyframes (values resolved relative to window/viewport at get time) +CIMGUI_API void c_iam_clip_key_float_rel(iam_clip* self, ImGuiID channel, float time, float percent, float px_bias, int anchor_space, int axis, int ease_type, float const* bezier4) { self->key_float_rel(channel, time, percent, px_bias, anchor_space, axis, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_vec2_rel(iam_clip* self, ImGuiID channel, float time, ImVec2* percent, ImVec2* px_bias, int anchor_space, int ease_type, float const* bezier4) { self->key_vec2_rel(channel, time, *percent, *px_bias, anchor_space, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_vec4_rel(iam_clip* self, ImGuiID channel, float time, ImVec4* percent, ImVec4* px_bias, int anchor_space, int ease_type, float const* bezier4) { self->key_vec4_rel(channel, time, *percent, *px_bias, anchor_space, ease_type, bezier4); } +CIMGUI_API void c_iam_clip_key_color_rel(iam_clip* self, ImGuiID channel, float time, ImVec4* percent, ImVec4* px_bias, int color_space, int anchor_space, int ease_type, float const* bezier4) { self->key_color_rel(channel, time, *percent, *px_bias, color_space, anchor_space, ease_type, bezier4); } + +// Timeline grouping - sequential and parallel keyframe blocks +CIMGUI_API void c_iam_clip_seq_begin(iam_clip* self) { self->seq_begin(); } +CIMGUI_API void c_iam_clip_seq_end(iam_clip* self) { self->seq_end(); } +CIMGUI_API void c_iam_clip_par_begin(iam_clip* self) { self->par_begin(); } +CIMGUI_API void c_iam_clip_par_end(iam_clip* self) { self->par_end(); } + +// Timeline markers - callbacks at specific times during playback +CIMGUI_API void c_iam_clip_marker_id(iam_clip* self, float time, ImGuiID marker_id, iam_marker_callback cb, void* user) { self->marker(time, marker_id, cb, user); } +CIMGUI_API void c_iam_clip_marker(iam_clip* self, float time, iam_marker_callback cb, void* user) { self->marker(time, cb, user); } + +// Clip options +CIMGUI_API void c_iam_clip_set_loop(iam_clip* self, bool loop, int direction, int loop_count) { self->set_loop(loop, direction, loop_count); } +CIMGUI_API void c_iam_clip_set_delay(iam_clip* self, float delay_seconds) { self->set_delay(delay_seconds); } +CIMGUI_API void c_iam_clip_set_stagger(iam_clip* self, int count, float each_delay, float from_center_bias) { self->set_stagger(count, each_delay, from_center_bias); } + +// Timing variation per loop iteration +CIMGUI_API void c_iam_clip_set_duration_var(iam_clip* self, iam_variation_float* var) { self->set_duration_var(*var); } +CIMGUI_API void c_iam_clip_set_delay_var(iam_clip* self, iam_variation_float* var) { self->set_delay_var(*var); } +CIMGUI_API void c_iam_clip_set_timescale_var(iam_clip* self, iam_variation_float* var) { self->set_timescale_var(*var); } + +// Callbacks +CIMGUI_API void c_iam_clip_on_begin(iam_clip* self, iam_clip_callback cb, void* user) { self->on_begin(cb, user); } +CIMGUI_API void c_iam_clip_on_update(iam_clip* self, iam_clip_callback cb, void* user) { self->on_update(cb, user); } +CIMGUI_API void c_iam_clip_on_complete(iam_clip* self, iam_clip_callback cb, void* user) { self->on_complete(cb, user); } + +CIMGUI_API void c_iam_clip_end(iam_clip* self) { self->end(); } + + +// ---------------------------------------------------- +// iam_instance - playback control for a clip +// ---------------------------------------------------- + +// Playback control +CIMGUI_API void c_iam_instance_pause(iam_instance* self) { self->pause(); } +CIMGUI_API void c_iam_instance_resume(iam_instance* self) { self->resume(); } +CIMGUI_API void c_iam_instance_stop(iam_instance* self) { self->stop(); } +CIMGUI_API void c_iam_instance_destroy_playback(iam_instance* self) { self->destroy(); } +CIMGUI_API void c_iam_instance_seek(iam_instance* self, float time) { self->seek(time); } +CIMGUI_API void c_iam_instance_set_time_scale(iam_instance* self, float scale) { self->set_time_scale(scale); } +CIMGUI_API void c_iam_instance_set_weight(iam_instance* self, float weight) { self->set_weight(weight); } + +// Animation chaining - play another clip when this one completes +CIMGUI_API void c_iam_instance_then(iam_instance* pOut, iam_instance* self, ImGuiID next_clip_id) { *pOut = self->then(next_clip_id); } +CIMGUI_API void c_iam_instance_then_id(iam_instance* pOut, iam_instance* self, ImGuiID next_clip_id, ImGuiID next_instance_id) { *pOut = self->then(next_clip_id, next_instance_id); } +CIMGUI_API void c_iam_instance_then_delay(iam_instance* pOut, iam_instance* self, float delay) { *pOut = self->then_delay(delay); } + +// Query state +CIMGUI_API float c_iam_instance_time(iam_instance* self) { return self->time(); } +CIMGUI_API float c_iam_instance_duration(iam_instance* self) { return self->duration(); } +CIMGUI_API bool c_iam_instance_is_playing(iam_instance* self) { return self->is_playing(); } +CIMGUI_API bool c_iam_instance_is_paused(iam_instance* self) { return self->is_paused(); } + +// Get animated values +CIMGUI_API bool c_iam_instance_get_float(iam_instance* self, ImGuiID channel, float* out) { return self->get_float(channel, out); } +CIMGUI_API bool c_iam_instance_get_vec2(iam_instance* self, ImGuiID channel, ImVec2* out) { return self->get_vec2(channel, out); } +CIMGUI_API bool c_iam_instance_get_vec4(iam_instance* self, ImGuiID channel, ImVec4* out) { return self->get_vec4(channel, out); } +CIMGUI_API bool c_iam_instance_get_int(iam_instance* self, ImGuiID channel, int* out) { return self->get_int(channel, out); } +CIMGUI_API bool c_iam_instance_get_color(iam_instance* self, ImGuiID channel, ImVec4* out, int color_space) { return self->get_color(channel, out, color_space); } + +// Check validity +CIMGUI_API bool c_iam_instance_valid(iam_instance* self) { return self->valid(); } + + +// ---------------------------------------------------- +// Clip System API +// ---------------------------------------------------- + +// Initialize/shutdown (optional - auto-init on first use) +CIMGUI_API void c_iam_clip_init(int initial_clip_cap, int initial_inst_cap) { iam_clip_init(initial_clip_cap, initial_inst_cap); } +CIMGUI_API void c_iam_clip_shutdown() { iam_clip_shutdown(); } + +// c_Per-frame update (call after iam_update_begin_frame) +CIMGUI_API void c_iam_clip_update(float dt) { iam_clip_update(dt); } + +// Garbage collection for instances +CIMGUI_API void c_iam_clip_gc(unsigned int max_age_frames) { iam_clip_gc(max_age_frames); } + +// Play a clip on an instance (creates or reuses instance) +CIMGUI_API void c_iam_play(iam_instance* pOut, ImGuiID clip_id, ImGuiID instance_id) { *pOut = iam_play(clip_id, instance_id); } + +// c_Get an existing instance (returns invalid iam_instance if not found) +CIMGUI_API void c_iam_get_instance(iam_instance* pOut, ImGuiID instance_id) { *pOut = iam_get_instance(instance_id); } + +// Query clip info +CIMGUI_API float c_iam_clip_duration(ImGuiID clip_id) { return iam_clip_duration(clip_id); } +CIMGUI_API bool c_iam_clip_exists(ImGuiID clip_id) { return iam_clip_exists(clip_id); } + +// Stagger helpers - compute delay for indexed instances +CIMGUI_API float c_iam_stagger_delay(ImGuiID clip_id, int index) { return iam_stagger_delay(clip_id, index); } +CIMGUI_API void c_iam_play_stagger(iam_instance* pOut, ImGuiID clip_id, ImGuiID instance_id, int index) { *pOut = iam_play_stagger(clip_id, instance_id, index); } + +// Layering support - blend multiple animation instances +CIMGUI_API void c_iam_layer_begin(ImGuiID instance_id) { iam_layer_begin(instance_id); } +CIMGUI_API void c_iam_layer_add(iam_instance* inst, float weight) { iam_layer_add(*inst, weight); } +CIMGUI_API void c_iam_layer_end(ImGuiID instance_id) { iam_layer_end(instance_id); } +CIMGUI_API bool c_iam_get_blended_float(ImGuiID instance_id, ImGuiID channel, float* out) { return iam_get_blended_float(instance_id, channel, out); } +CIMGUI_API bool c_iam_get_blended_vec2(ImGuiID instance_id, ImGuiID channel, ImVec2* out) { return iam_get_blended_vec2(instance_id, channel, out); } +CIMGUI_API bool c_iam_get_blended_vec4(ImGuiID instance_id, ImGuiID channel, ImVec4* out) { return iam_get_blended_vec4(instance_id, channel, out); } +CIMGUI_API bool c_iam_get_blended_int(ImGuiID instance_id, ImGuiID channel, int* out) { return iam_get_blended_int(instance_id, channel, out); } + +// Persistence (optional) +CIMGUI_API iam_result c_iam_clip_save(ImGuiID clip_id, char const* path) { return iam_clip_save(clip_id, path); } +CIMGUI_API iam_result c_iam_clip_load(char const* path, ImGuiID* out_clip_id) { return iam_clip_load(path, out_clip_id); } diff --git a/external/cimanim/cimanim.h b/external/cimanim/cimanim.h new file mode 100644 index 000000000..9cc9ba967 --- /dev/null +++ b/external/cimanim/cimanim.h @@ -0,0 +1,443 @@ +#pragma once +#include "imgui.h" +#include "imgui_internal.h" +#include "cimgui.h" +#include "im_anim.h" + +extern void ImAnimDemoWindow(); + +// ---------------------------------------------------- +// Public API declarations +// ---------------------------------------------------- + +CIMGUI_API void c_iam_set_imgui_context(ImGuiContext* context); +CIMGUI_API void c_iam_demo_window(); + +// Frame management +CIMGUI_API void c_iam_update_begin_frame(); +CIMGUI_API void c_iam_gc(unsigned int max_age_frames); +CIMGUI_API void c_iam_reserve(int cap_float, int cap_vec2, int cap_vec4, int cap_int, int cap_color); +CIMGUI_API void c_iam_set_ease_lut_samples(int count); + +// Global time scale (for slow-motion / fast-forward debugging) +CIMGUI_API void c_iam_set_global_time_scale(float scale); +CIMGUI_API float c_iam_get_global_time_scale(); + +// Lazy Initialization - defer channel creation until animation is needed +CIMGUI_API void c_iam_set_lazy_init(bool enable); +CIMGUI_API bool c_iam_is_lazy_init_enabled(); + +CIMGUI_API void c_iam_register_custom_ease(int slot, iam_ease_fn fn); +CIMGUI_API void c_iam_get_custom_ease(iam_ease_fn* pOut, int slot); + +// Debug UI +CIMGUI_API void c_iam_show_unified_inspector(bool* p_open); + +// Performance Profiler +CIMGUI_API void c_iam_profiler_enable(bool enable); +CIMGUI_API bool c_iam_profiler_is_enabled(); +CIMGUI_API void c_iam_profiler_begin_frame(); +CIMGUI_API void c_iam_profiler_end_frame(); +CIMGUI_API void c_iam_profiler_begin(const char* name); +CIMGUI_API void c_iam_profiler_end(); + +// Drag Feedback - animated feedback for drag operations +CIMGUI_API void c_iam_drag_begin(iam_drag_feedback* pOut, ImGuiID id, ImVec2* pos); +CIMGUI_API void c_iam_drag_update(iam_drag_feedback* pOut, ImGuiID id, ImVec2* pos, float dt); +CIMGUI_API void c_iam_drag_release(iam_drag_feedback* pOut, ImGuiID id, ImVec2* pos, iam_drag_opts* opts, float dt); +CIMGUI_API void c_iam_drag_cancel(ImGuiID id); + +// Oscillators - continuous periodic animations +CIMGUI_API float c_iam_oscillate(ImGuiID id, float amplitude, float frequency, int wave_type, float phase, float dt); +CIMGUI_API int c_iam_oscillate_int(ImGuiID id, int amplitude, float frequency, int wave_type, float phase, float dt); +CIMGUI_API void c_iam_oscillate_vec2(ImVec2* pOut, ImGuiID id, ImVec2* amplitude, ImVec2* frequency, int wave_type, ImVec2* phase, float dt); +CIMGUI_API void c_iam_oscillate_vec4(ImVec4* pOut, ImGuiID id, ImVec4* amplitude, ImVec4* frequency, int wave_type, ImVec4* phase, float dt); +CIMGUI_API void c_iam_oscillate_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float frequency, int wave_type, float phase, int color_space, float dt); + +// Shake/Wiggle - procedural noise animations +CIMGUI_API float c_iam_shake(ImGuiID id, float intensity, float frequency, float decay_time, float dt); +CIMGUI_API int c_iam_shake_int(ImGuiID id, int intensity, float frequency, float decay_time, float dt); +CIMGUI_API void c_iam_shake_vec2(ImVec2* pOut, ImGuiID id, ImVec2* intensity, float frequency, float decay_time, float dt); +CIMGUI_API void c_iam_shake_vec4(ImVec4* pOut, ImGuiID id, ImVec4* intensity, float frequency, float decay_time, float dt); +CIMGUI_API void c_iam_shake_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* intensity, float frequency, float decay_time, int color_space, float dt); +CIMGUI_API float c_iam_wiggle(ImGuiID id, float amplitude, float frequency, float dt); +CIMGUI_API int c_iam_wiggle_int(ImGuiID id, int amplitude, float frequency, float dt); +CIMGUI_API void c_iam_wiggle_vec2(ImVec2* pOut, ImGuiID id, ImVec2* amplitude, float frequency, float dt); +CIMGUI_API void c_iam_wiggle_vec4(ImVec4* pOut, ImGuiID id, ImVec4* amplitude, float frequency, float dt); +CIMGUI_API void c_iam_wiggle_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float frequency, int color_space, float dt); +CIMGUI_API void c_iam_trigger_shake(ImGuiID id); + +// Easing evaluation +CIMGUI_API float c_iam_eval_preset(int type, float t); + +// Tween API - smoothly interpolate values over time +CIMGUI_API float c_iam_tween_float(ImGuiID id, ImGuiID channel_id, float target, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_vec2(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImVec2* target, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_vec4(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API int c_iam_tween_int(ImGuiID id, ImGuiID channel_id, int target, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_color(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target_srgb, float dur, iam_ease_desc* ez, int policy, int color_space, float dt); + +// Resize-friendly helpers +CIMGUI_API void c_iam_anchor_size(ImVec2* pOut, int space); + +// Relative target tweens (percent of anchor + pixel offset) - survive window resizes +CIMGUI_API float c_iam_tween_float_rel(ImGuiID id, ImGuiID channel_id, float percent, float px_bias, float dur, iam_ease_desc* ez, int policy, int anchor_space, int axis, float dt); +CIMGUI_API void c_iam_tween_vec2_rel(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImVec2* percent, ImVec2* px_bias, float dur, iam_ease_desc* ez, int policy, int anchor_space, float dt); +CIMGUI_API void c_iam_tween_vec4_rel(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* percent, ImVec4* px_bias, float dur, iam_ease_desc* ez, int policy, int anchor_space, float dt); +CIMGUI_API void c_iam_tween_color_rel(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* percent, ImVec4* px_bias, float dur, iam_ease_desc* ez, int policy, int color_space, int anchor_space, float dt); + +// Rebase functions - change target of in-progress animation without restarting +CIMGUI_API void c_iam_rebase_float(ImGuiID id, ImGuiID channel_id, float new_target, float dt); +CIMGUI_API void c_iam_rebase_vec2(ImGuiID id, ImGuiID channel_id, ImVec2* new_target, float dt); +CIMGUI_API void c_iam_rebase_vec4(ImGuiID id, ImGuiID channel_id, ImVec4* new_target, float dt); +CIMGUI_API void c_iam_rebase_color(ImGuiID id, ImGuiID channel_id, ImVec4* new_target, float dt); +CIMGUI_API void c_iam_rebase_int(ImGuiID id, ImGuiID channel_id, int new_target, float dt); + +// Resolved tweens - target computed dynamically by callback each frame +CIMGUI_API float c_iam_tween_float_resolved(ImGuiID id, ImGuiID channel_id, iam_float_resolver, void* user, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_vec2_resolved(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, iam_vec2_resolver, void* user, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_vec4_resolved(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, iam_vec4_resolver, void* user, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_color_resolved(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, iam_vec4_resolver, void* user, float dur, iam_ease_desc* ez, int policy, int color_space, float dt); +CIMGUI_API int c_iam_tween_int_resolved(ImGuiID id, ImGuiID channel_id, iam_int_resolver, void* user, float dur, iam_ease_desc* ez, int policy, float dt); + +// Color blending utility +CIMGUI_API void c_iam_get_blended_color(ImVec4* pOut, ImVec4* a_srgb, ImVec4* b_srgb, float t, int color_space); + + +// ---------------------------------------------------- +// Convenience shorthands for common easings +// ---------------------------------------------------- + +CIMGUI_API void c_iam_ease_preset(iam_ease_desc* pOut, int type); +CIMGUI_API void c_iam_ease_bezier(iam_ease_desc* pOut, float x1, float y1, float x2, float y2); +CIMGUI_API void c_iam_ease_steps_desc(iam_ease_desc* pOut, int steps, int mode); +CIMGUI_API void c_iam_ease_back(iam_ease_desc* pOut, float overshoot); +CIMGUI_API void c_iam_ease_elastic(iam_ease_desc* pOut, float amplitude, float period); +CIMGUI_API void c_iam_ease_spring_desc(iam_ease_desc* pOut, float mass, float stiffness, float damping, float v0); +CIMGUI_API void c_iam_ease_custom_fn(iam_ease_desc* pOut, int slot); + +// Scroll animation - smooth scrolling for ImGui windows +CIMGUI_API void c_iam_scroll_to_y(float target_y, float duration, iam_ease_desc* ez); +CIMGUI_API void c_iam_scroll_to_x(float target_x, float duration, iam_ease_desc* ez); +CIMGUI_API void c_iam_scroll_to_top(float duration, iam_ease_desc* ez); +CIMGUI_API void c_iam_scroll_to_bottom(float duration, iam_ease_desc* ez); + + +// ---------------------------------------------------- +// Per-axis easing - different easing per component +// ---------------------------------------------------- + +// Tween with per-axis easing - each component uses its own easing curve +CIMGUI_API void c_iam_tween_vec2_per_axis(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImVec2* target, float dur, iam_ease_per_axis* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_vec4_per_axis(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target, float dur, iam_ease_per_axis* ez, int policy, float dt); +CIMGUI_API void c_iam_tween_color_per_axis(ImVec4* pOut, ImGuiID id, ImGuiID channel_id, ImVec4* target_srgb, float dur, iam_ease_per_axis* ez, int policy, int color_space, float dt); + + +// ---------------------------------------------------- +// Motion Paths - animate along curves and splines +// ---------------------------------------------------- + +// Single-curve evaluation functions (stateless, for direct use) +CIMGUI_API void c_iam_bezier_quadratic(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, float t); +CIMGUI_API void c_iam_bezier_cubic(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t); +CIMGUI_API void c_iam_catmull_rom(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t, float tension); + +// Derivatives (for tangent/velocity) +CIMGUI_API void c_iam_bezier_quadratic_deriv(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, float t); +CIMGUI_API void c_iam_bezier_cubic_deriv(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t); +CIMGUI_API void c_iam_catmull_rom_deriv(ImVec2* pOut, ImVec2* p0, ImVec2* p1, ImVec2* p2, ImVec2* p3, float t, float tension); + +// Query path info +CIMGUI_API bool c_iam_path_exists(ImGuiID path_id); +CIMGUI_API float c_iam_path_length(ImGuiID path_id); +CIMGUI_API void c_iam_path_evaluate(ImVec2* pOut, ImGuiID path_id, float t); +CIMGUI_API void c_iam_path_tangent(ImVec2* pOut, ImGuiID path_id, float t); +CIMGUI_API float c_iam_path_angle(ImGuiID path_id, float t); + +// Tween along a path +CIMGUI_API void c_iam_tween_path(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImGuiID path_id, float dur, iam_ease_desc* ez, int policy, float dt); +CIMGUI_API float c_iam_tween_path_angle(ImGuiID id, ImGuiID channel_id, ImGuiID path_id, float dur, iam_ease_desc* ez, int policy, float dt); + + +// ---------------------------------------------------- +// Arc-length parameterization (for constant-speed animation) +// ---------------------------------------------------- + +// Build arc-length lookup table for a path (call once per path, improves accuracy) +CIMGUI_API void c_iam_path_build_arc_lut(ImGuiID path_id, int subdivisions); +CIMGUI_API bool c_iam_path_has_arc_lut(ImGuiID path_id); + +// Distance-based path evaluation (uses arc-length LUT for constant speed) +CIMGUI_API float c_iam_path_distance_to_t(ImGuiID path_id, float distance); +CIMGUI_API void c_iam_path_evaluate_at_distance(ImVec2* pOut, ImGuiID path_id, float distance); +CIMGUI_API float c_iam_path_angle_at_distance(ImGuiID path_id, float distance); +CIMGUI_API void c_iam_path_tangent_at_distance(ImVec2* pOut, ImGuiID path_id, float distance); + + +// ---------------------------------------------------- +// Path Morphing - interpolate between two paths +// ---------------------------------------------------- + +// Evaluate morphed path at parameter t [0,1] with blend factor [0,1] +// path_a at blend=0, path_b at blend=1 +// Paths can have different numbers of segments - they are resampled to match +CIMGUI_API void c_iam_path_morph(ImVec2* pOut, ImGuiID path_a, ImGuiID path_b, float t, float blend, iam_morph_opts* opts); + +// Get tangent of morphed path +CIMGUI_API void c_iam_path_morph_tangent(ImVec2* pOut, ImGuiID path_a, ImGuiID path_b, float t, float blend, iam_morph_opts* opts); + +// Get angle (radians) of morphed path +CIMGUI_API float c_iam_path_morph_angle(ImGuiID path_a, ImGuiID path_b, float t, float blend, iam_morph_opts* opts); + +// Tween along a morphing path - animates both position along path AND the morph blend +CIMGUI_API void c_iam_tween_path_morph(ImVec2* pOut, ImGuiID id, ImGuiID channel_id, ImGuiID path_a, ImGuiID path_b, float target_blend, float dur, iam_ease_desc* path_ease, iam_ease_desc* morph_ease, int policy, float dt, iam_morph_opts* opts); + +// Get current morph blend value from a tween (for querying state) +CIMGUI_API float c_iam_get_morph_blend(ImGuiID id, ImGuiID channel_id); + + +// ---------------------------------------------------- +// Text along motion paths +// ---------------------------------------------------- + +// Render text along a path (static - no animation) +CIMGUI_API void c_iam_text_path(ImGuiID path_id, const char* text, iam_text_path_opts* opts); + +// Animated text along path (characters appear progressively) +CIMGUI_API void c_iam_text_path_animated(ImGuiID path_id, const char* text, float progress, iam_text_path_opts* opts); + +// Helper: Get text width for path layout calculations +CIMGUI_API float c_iam_text_path_width(const char* text, iam_text_path_opts* opts); + + +// ---------------------------------------------------- +// Quad transform helpers (for advanced custom rendering) +// ---------------------------------------------------- + +// Transform a quad (4 vertices) by rotation and translation +CIMGUI_API void c_iam_transform_quad(ImVec2* quad, ImVec2* center, float angle_rad, ImVec2* translation); + +// Create a rotated quad for a glyph at a position on the path +CIMGUI_API void c_iam_make_glyph_quad(ImVec2* quad, ImVec2* pos, float angle_rad, float glyph_width, float glyph_height, float baseline_offset); + + +// ---------------------------------------------------- +// Text Stagger - per-character animation effects +// ---------------------------------------------------- + +// Render text with per-character stagger animation +CIMGUI_API void c_iam_text_stagger(ImGuiID id, const char* text, float progress, iam_text_stagger_opts* opts); + +// Get text width for layout calculations +CIMGUI_API float c_iam_text_stagger_width(const char* text, iam_text_stagger_opts* opts); + +// Get total animation duration for text (accounts for stagger delays) +CIMGUI_API float c_iam_text_stagger_duration(const char* text, iam_text_stagger_opts* opts); + + +// ---------------------------------------------------- +// Noise Channels - Perlin/Simplex noise for organic movement +// ---------------------------------------------------- + +// Sample noise at a point (returns value in [-1, 1]) +CIMGUI_API float c_iam_noise_2d(float x, float y, iam_noise_opts* opts); +CIMGUI_API float c_iam_noise_3d(float x, float y, float z, iam_noise_opts* opts); + +// Animated noise channels - continuous noise that evolves over time +CIMGUI_API float c_iam_noise_channel_float(ImGuiID id, float frequency, float amplitude, iam_noise_opts* opts, float dt); +CIMGUI_API void c_iam_noise_channel_vec2(ImVec2* pOut, ImGuiID id, ImVec2* frequency, ImVec2* amplitude, iam_noise_opts* opts, float dt); +CIMGUI_API void c_iam_noise_channel_vec4(ImVec4* pOut, ImGuiID id, ImVec4* frequency, ImVec4* amplitude, iam_noise_opts* opts, float dt); +CIMGUI_API void c_iam_noise_channel_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float frequency, iam_noise_opts* opts, int color_space, float dt); + +// Convenience: smooth random movement (like wiggle but using noise) +CIMGUI_API float c_iam_smooth_noise_float(ImGuiID id, float amplitude, float speed, float dt); +CIMGUI_API void c_iam_smooth_noise_vec2(ImVec2* pOut, ImGuiID id, ImVec2* amplitude, float speed, float dt); +CIMGUI_API void c_iam_smooth_noise_vec4(ImVec4* pOut, ImGuiID id, ImVec4* amplitude, float speed, float dt); +CIMGUI_API void c_iam_smooth_noise_color(ImVec4* pOut, ImGuiID id, ImVec4* base_color, ImVec4* amplitude, float speed, int color_space, float dt); + + +// ---------------------------------------------------- +// Style Interpolation - animate between ImGuiStyle themes +// ---------------------------------------------------- + +// Register a named style for interpolation +CIMGUI_API void c_iam_style_register(ImGuiID style_id, ImGuiStyle* style); +CIMGUI_API void c_iam_style_register_current(ImGuiID style_id); + +// Blend between two registered styles (result applied to ImGui::GetStyle()) +// Uses iam_color_space for color blending mode (iam_col_oklab recommended) +CIMGUI_API void c_iam_style_blend(ImGuiID style_a, ImGuiID style_b, float t, int color_space); + +// Tween between styles over time +CIMGUI_API void c_iam_style_tween(ImGuiID id, ImGuiID target_style, float duration, iam_ease_desc* ease, int color_space, float dt); + +// Get interpolated style without applying +CIMGUI_API void c_iam_style_blend_to(ImGuiID style_a, ImGuiID style_b, float t, ImGuiStyle* out_style, int color_space); + +// Check if a style is registered +CIMGUI_API bool c_iam_style_exists(ImGuiID style_id); + +// Remove a registered style +CIMGUI_API void c_iam_style_unregister(ImGuiID style_id); + + +// ---------------------------------------------------- +// Gradient Interpolation - animate between color gradients +// ---------------------------------------------------- + +// Blend between two gradients +CIMGUI_API void c_iam_gradient_lerp(iam_gradient* pOut, iam_gradient* a, iam_gradient* b, float t, int color_space); + +// Tween between gradients over time +CIMGUI_API void c_iam_tween_gradient(iam_gradient* pOut, ImGuiID id, ImGuiID channel_id, iam_gradient* target, float dur, iam_ease_desc* ez, int policy, int color_space, float dt); + + +// ---------------------------------------------------- +// Transform Interpolation - animate 2D transforms +// ---------------------------------------------------- + +// Blend between two transforms with rotation interpolation +CIMGUI_API void c_iam_transform_lerp(iam_transform* pOut, iam_transform* a, iam_transform* b, float t, int rotation_mode); + +// Tween between transforms over time +CIMGUI_API void c_iam_tween_transform(iam_transform* pOut, ImGuiID id, ImGuiID channel_id, iam_transform* target, float dur, iam_ease_desc* ez, int policy, int rotation_mode, float dt); + +// Decompose a 3x2 matrix into transform components +CIMGUI_API void c_iam_transform_from_matrix(iam_transform* pOut, float m00, float m01, float m10, float m11, float tx, float ty); + +// Convert transform to 3x2 matrix (row-major: [m00 m01 tx; m10 m11 ty]) +CIMGUI_API void c_iam_transform_to_matrix(iam_transform* t, float* out_matrix); + + +// ---------------------------------------------------- +// iam_clip - fluent API for authoring animations +// ---------------------------------------------------- + +CIMGUI_API void c_iam_clip_begin(iam_clip* pOut, ImGuiID clip_id); + +// Add keyframes for different channel types +CIMGUI_API void c_iam_clip_key_float(iam_clip* self, ImGuiID channel, float time, float value, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_vec2(iam_clip* self, ImGuiID channel, float time, ImVec2* value, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_vec4(iam_clip* self, ImGuiID channel, float time, ImVec4* value, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_int(iam_clip* self, ImGuiID channel, float time, int value, int ease_type); +CIMGUI_API void c_iam_clip_key_color(iam_clip* self, ImGuiID channel, float time, ImVec4* value, int color_space, int ease_type, float const* bezier4); + +// Keyframes with repeat variation (value changes per loop iteration) +CIMGUI_API void c_iam_clip_key_float_var(iam_clip* self, ImGuiID channel, float time, float value, iam_variation_float* var, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_vec2_var(iam_clip* self, ImGuiID channel, float time, ImVec2* value, iam_variation_vec2* var, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_vec4_var(iam_clip* self, ImGuiID channel, float time, ImVec4* value, iam_variation_vec4* var, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_int_var(iam_clip* self, ImGuiID channel, float time, int value, iam_variation_int* var, int ease_type); +CIMGUI_API void c_iam_clip_key_color_var(iam_clip* self, ImGuiID channel, float time, ImVec4* value, iam_variation_color* var, int color_space, int ease_type, float const* bezier4); + +// Spring-based keyframe (float only) +CIMGUI_API void c_iam_clip_key_float_spring(iam_clip* self, ImGuiID channel, float time, float target, iam_spring_params* spring); + +// Anchor-relative keyframes (values resolved relative to window/viewport at get time) +CIMGUI_API void c_iam_clip_key_float_rel(iam_clip* self, ImGuiID channel, float time, float percent, float px_bias, int anchor_space, int axis, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_vec2_rel(iam_clip* self, ImGuiID channel, float time, ImVec2* percent, ImVec2* px_bias, int anchor_space, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_vec4_rel(iam_clip* self, ImGuiID channel, float time, ImVec4* percent, ImVec4* px_bias, int anchor_space, int ease_type, float const* bezier4); +CIMGUI_API void c_iam_clip_key_color_rel(iam_clip* self, ImGuiID channel, float time, ImVec4* percent, ImVec4* px_bias, int color_space, int anchor_space, int ease_type, float const* bezier4); + +// Timeline grouping - sequential and parallel keyframe blocks +CIMGUI_API void c_iam_clip_seq_begin(iam_clip* self); +CIMGUI_API void c_iam_clip_seq_end(iam_clip* self); +CIMGUI_API void c_iam_clip_par_begin(iam_clip* self); +CIMGUI_API void c_iam_clip_par_end(iam_clip* self); + +// Timeline markers - callbacks at specific times during playback +CIMGUI_API void c_iam_clip_marker_id(iam_clip* self, float time, ImGuiID marker_id, iam_marker_callback cb, void* user); +CIMGUI_API void c_iam_clip_marker(iam_clip* self, float time, iam_marker_callback cb, void* user); + +// Clip options +CIMGUI_API void c_iam_clip_set_loop(iam_clip* self, bool loop, int direction, int loop_count); +CIMGUI_API void c_iam_clip_set_delay(iam_clip* self, float delay_seconds); +CIMGUI_API void c_iam_clip_set_stagger(iam_clip* self, int count, float each_delay, float from_center_bias); + +// Timing variation per loop iteration +CIMGUI_API void c_iam_clip_set_duration_var(iam_clip* self, iam_variation_float* var); +CIMGUI_API void c_iam_clip_set_delay_var(iam_clip* self, iam_variation_float* var); +CIMGUI_API void c_iam_clip_set_timescale_var(iam_clip* self, iam_variation_float* var); + +// Callbacks +CIMGUI_API void c_iam_clip_on_begin(iam_clip* self, iam_clip_callback cb, void* user); +CIMGUI_API void c_iam_clip_on_update(iam_clip* self, iam_clip_callback cb, void* user); +CIMGUI_API void c_iam_clip_on_complete(iam_clip* self, iam_clip_callback cb, void* user); + +CIMGUI_API void c_iam_clip_end(iam_clip* self); + + +// ---------------------------------------------------- +// iam_instance - playback control for a clip +// ---------------------------------------------------- + +// Playback control +CIMGUI_API void c_iam_instance_pause(iam_instance* self); +CIMGUI_API void c_iam_instance_resume(iam_instance* self); +CIMGUI_API void c_iam_instance_stop(iam_instance* self); +CIMGUI_API void c_iam_instance_destroy_playback(iam_instance* self); +CIMGUI_API void c_iam_instance_seek(iam_instance* self, float time); +CIMGUI_API void c_iam_instance_set_time_scale(iam_instance* self, float scale); +CIMGUI_API void c_iam_instance_set_weight(iam_instance* self, float weight); + +// Animation chaining - play another clip when this one completes +CIMGUI_API void c_iam_instance_then(iam_instance* pOut, iam_instance* self, ImGuiID next_clip_id); +CIMGUI_API void c_iam_instance_then_id(iam_instance* pOut, iam_instance* self, ImGuiID next_clip_id, ImGuiID next_instance_id); +CIMGUI_API void c_iam_instance_then_delay(iam_instance* pOut, iam_instance* self, float delay); + +// Query state +CIMGUI_API float c_iam_instance_time(iam_instance* self); +CIMGUI_API float c_iam_instance_duration(iam_instance* self); +CIMGUI_API bool c_iam_instance_is_playing(iam_instance* self); +CIMGUI_API bool c_iam_instance_is_paused(iam_instance* self); + +// Get animated values +CIMGUI_API bool c_iam_instance_get_float(iam_instance* self, ImGuiID channel, float* out); +CIMGUI_API bool c_iam_instance_get_vec2(iam_instance* self, ImGuiID channel, ImVec2* out); +CIMGUI_API bool c_iam_instance_get_vec4(iam_instance* self, ImGuiID channel, ImVec4* out); +CIMGUI_API bool c_iam_instance_get_int(iam_instance* self, ImGuiID channel, int* out); +CIMGUI_API bool c_iam_instance_get_color(iam_instance* self, ImGuiID channel, ImVec4* out, int color_space); + +// Check validity +CIMGUI_API bool c_iam_instance_valid(iam_instance* self); + + +// ---------------------------------------------------- +// Clip System API +// ---------------------------------------------------- + +// Initialize/shutdown (optional - auto-init on first use) +CIMGUI_API void c_iam_clip_init(int initial_clip_cap, int initial_inst_cap); +CIMGUI_API void c_iam_clip_shutdown(); + +// c_Per-frame update (call after iam_update_begin_frame) +CIMGUI_API void c_iam_clip_update(float dt); + +// Garbage collection for instances +CIMGUI_API void c_iam_clip_gc(unsigned int max_age_frames); + +// Play a clip on an instance (creates or reuses instance) +CIMGUI_API void c_iam_play(iam_instance* pOut, ImGuiID clip_id, ImGuiID instance_id); + +// c_Get an existing instance (returns invalid iam_instance if not found) +CIMGUI_API void c_iam_get_instance(iam_instance* pOut, ImGuiID instance_id); + +// Query clip info +CIMGUI_API float c_iam_clip_duration(ImGuiID clip_id); +CIMGUI_API bool c_iam_clip_exists(ImGuiID clip_id); + +// Stagger helpers - compute delay for indexed instances +CIMGUI_API float c_iam_stagger_delay(ImGuiID clip_id, int index); +CIMGUI_API void c_iam_play_stagger(iam_instance* pOut, ImGuiID clip_id, ImGuiID instance_id, int index); + +// Layering support - blend multiple animation instances +CIMGUI_API void c_iam_layer_begin(ImGuiID instance_id); +CIMGUI_API void c_iam_layer_add(iam_instance* inst, float weight); +CIMGUI_API void c_iam_layer_end(ImGuiID instance_id); +CIMGUI_API bool c_iam_get_blended_float(ImGuiID instance_id, ImGuiID channel, float* out); +CIMGUI_API bool c_iam_get_blended_vec2(ImGuiID instance_id, ImGuiID channel, ImVec2* out); +CIMGUI_API bool c_iam_get_blended_vec4(ImGuiID instance_id, ImGuiID channel, ImVec4* out); +CIMGUI_API bool c_iam_get_blended_int(ImGuiID instance_id, ImGuiID channel, int* out); + +// Persistence (optional) +CIMGUI_API iam_result c_iam_clip_save(ImGuiID clip_id, char const* path); +CIMGUI_API iam_result c_iam_clip_load(char const* path, ImGuiID* out_clip_id); diff --git a/external/cimanim/cimanim.vcxproj b/external/cimanim/cimanim.vcxproj new file mode 100644 index 000000000..1bf00367c --- /dev/null +++ b/external/cimanim/cimanim.vcxproj @@ -0,0 +1,108 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + 17.0 + Win32Proj + {9E65E2A1-1337-4180-87D9-1234567890AB} + cimanim + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + bin\$(Configuration)\ + obj\$(Configuration)\ + + + + ..\..\lib\cimgui\imgui;..\..\lib\ImAnim;..\..\lib\cimgui;%(AdditionalIncludeDirectories) + NotUsing + + + + + Level3 + true + _DEBUG;CIMANIM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreadedDebugDLL + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;CIMANIM_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + + + Windows + true + true + true + false + + + + + + + + + + diff --git a/imgui/Dalamud.Bindings.ImAnim/Dalamud.Bindings.ImAnim.csproj b/imgui/Dalamud.Bindings.ImAnim/Dalamud.Bindings.ImAnim.csproj new file mode 100644 index 000000000..7f7818083 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Dalamud.Bindings.ImAnim.csproj @@ -0,0 +1,13 @@ + + + + enable + enable + true + true + + + + + + diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimAnchorSpace.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimAnchorSpace.cs new file mode 100644 index 000000000..618795feb --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimAnchorSpace.cs @@ -0,0 +1,24 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimAnchorSpace +{ + /// + /// ImGui::GetContentRegionAvail() + /// + WindowContent, + + /// + /// ImGui::GetWindowSize() + /// + Window, + + /// + /// ImGui::GetWindowViewport()->Size + /// + Viewport, + + /// + /// ImGui::GetItemRectSize() + /// + LastItem, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimColorSpace.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimColorSpace.cs new file mode 100644 index 000000000..63ec507b3 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimColorSpace.cs @@ -0,0 +1,29 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimColorSpace +{ + /// + /// blend in sRGB (not physically linear) + /// + Srgb, + + /// + /// sRGB<->linear, blend in linear, back to sRGB + /// + SrgbLinear, + + /// + /// blend H/S/V (hue shortest arc), keep A linear + /// + Hsv, + + /// + /// sRGB<->OKLAB, blend in OKLAB, back to sRGB + /// + Oklab, + + /// + /// sRGB<->OKLCH (cylindrical OKLAB), blend in OKLCH, back to sRGB + /// + Oklch, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimDirection.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimDirection.cs new file mode 100644 index 000000000..53ba81ff6 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimDirection.cs @@ -0,0 +1,19 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimDirection +{ + /// + /// play forward + /// + Normal, + + /// + /// play backward + /// + Reverse, + + /// + /// ping-pong + /// + Alternate, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseStepsMode.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseStepsMode.cs new file mode 100644 index 000000000..1d889c4f0 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseStepsMode.cs @@ -0,0 +1,8 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimEaseStepsMode +{ + End, + Start, + Both, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseType.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseType.cs new file mode 100644 index 000000000..73d3fdd5a --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimEaseType.cs @@ -0,0 +1,70 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimEaseType +{ + Linear, + InQuad, + OutQuad, + InOutQuad, + InCubic, + OutCubic, + InOutCubic, + InQuart, + OutQuart, + InOutQuart, + InQuint, + OutQuint, + InOutQuint, + InSine, + OutSine, + InOutSine, + InExpo, + OutExpo, + InOutExpo, + InCirc, + OutCirc, + InOutCirc, + /// + /// p0 = overshoot + /// + InBack, + /// + /// p0 = overshoot + /// + OutBack, + /// + /// p0 = overshoot + /// + InOutBack, + /// + /// p0 = amplitude, p1 = period + /// + InElastic, + /// + /// p0 = amplitude, p1 = period + /// + OutElastic, + /// + /// p0 = amplitude, p1 = period + /// + InOutElastic, + InBounce, + OutBounce, + InOutBounce, + /// + /// p0 = steps (>=1), p1 = 0:end 1:start 2:both + /// + Steps, + /// + /// p0=x1 p1=y1 p2=x2 p3=y2 + /// + CubicBezier, + /// + /// p0=mass p1=stiffness p2=damping p3=v0 + /// + Spring, + /// + /// User-defined easing function (use iam_ease_custom_fn) + /// + Custom, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimNoiseType.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimNoiseType.cs new file mode 100644 index 000000000..dd20c7370 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimNoiseType.cs @@ -0,0 +1,24 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimNoiseType +{ + /// + /// Classic Perlin noise + /// + Perlin, + + /// + /// Simplex noise (faster, fewer artifacts) + /// + Simplex, + + /// + /// Value noise (blocky) + /// + Value, + + /// + /// Worley/cellular noise + /// + Worley, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimPolicy.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimPolicy.cs new file mode 100644 index 000000000..cf97f9b8b --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimPolicy.cs @@ -0,0 +1,19 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimPolicy +{ + /// + /// smooth into new target + /// + Crossfade, + + /// + /// snap to target + /// + Cut, + + /// + /// queue one pending target + /// + Queue, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimResult.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimResult.cs new file mode 100644 index 000000000..a626a51b3 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimResult.cs @@ -0,0 +1,9 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimResult +{ + Ok, + ErrNotFound, + ErrBadArg, + ErrNoMem, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimRotationMode.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimRotationMode.cs new file mode 100644 index 000000000..d788962c7 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimRotationMode.cs @@ -0,0 +1,29 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimRotationMode +{ + /// + /// Shortest path (default) - never rotates more than 180 degrees + /// + Shortest, + + /// + /// Longest path - always takes the long way around + /// + Longest, + + /// + /// Clockwise - always rotates clockwise (positive direction) + /// + Cw, + + /// + /// Counter-clockwise - always rotates counter-clockwise + /// + Ccw, + + /// + /// Direct lerp - no angle unwrapping, can cause spinning for large deltas + /// + Direct, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextPathAlign.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextPathAlign.cs new file mode 100644 index 000000000..c3fa098c4 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextPathAlign.cs @@ -0,0 +1,19 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimTextPathAlign +{ + /// + /// Text starts at path start (or offset) + /// + Start, + + /// + /// Text centered on path + /// + Center, + + /// + /// Text ends at path end + /// + End, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextStaggerEffect.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextStaggerEffect.cs new file mode 100644 index 000000000..f6269befe --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimTextStaggerEffect.cs @@ -0,0 +1,59 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimTextStaggerEffect +{ + /// + /// No effect (instant appear) + /// + None, + + /// + /// Fade in alpha + /// + Fade, + + /// + /// Scale from center + /// + Scale, + + /// + /// Slide up from below + /// + SlideUp, + + /// + /// Slide down from above + /// + SlideDown, + + /// + /// Slide in from right + /// + SlideLeft, + + /// + /// Slide in from left + /// + SlideRight, + + /// + /// Rotate in + /// + Rotate, + + /// + /// Bounce in with overshoot + /// + Bounce, + + /// + /// Wave motion (continuous) + /// + Wave, + + /// + /// Typewriter style (instant per char) + /// + Typewriter, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimVariationMode.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimVariationMode.cs new file mode 100644 index 000000000..0b5940b10 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimVariationMode.cs @@ -0,0 +1,44 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimVariationMode +{ + /// + /// No variation + /// + None, + + /// + /// Add amount each iteration + /// + Increment, + + /// + /// Subtract amount each iteration + /// + Decrement, + + /// + /// Multiply by factor each iteration + /// + Multiply, + + /// + /// Random in range [-amount, +amount] + /// + Random, + + /// + /// Random in range [0, amount] + /// + RandomAbs, + + /// + /// Alternate +/- each iteration + /// + PingPong, + + /// + /// Use custom callback + /// + Callback, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimWaveType.cs b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimWaveType.cs new file mode 100644 index 000000000..1a2eb0b53 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Enums/ImAnimWaveType.cs @@ -0,0 +1,24 @@ +namespace Dalamud.Bindings.ImAnim; + +public enum ImAnimWaveType +{ + /// + /// Smooth sine wave + /// + Sine, + + /// + /// Triangle wave (linear up/down) + /// + Triangle, + + /// + /// Sawtooth wave (linear up, instant reset) + /// + Sawtooth, + + /// + /// Square wave (on/off pulse) + /// + Square, +} diff --git a/imgui/Dalamud.Bindings.ImAnim/ImAnim.cs b/imgui/Dalamud.Bindings.ImAnim/ImAnim.cs new file mode 100644 index 000000000..f1be3bd87 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/ImAnim.cs @@ -0,0 +1,1236 @@ +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +using Dalamud.Bindings.ImGui; + +namespace Dalamud.Bindings.ImAnim; + +public static unsafe class ImAnim +{ + public delegate void ClipCallback(uint inst_id, void* user_data); // iam_clip_callback + public delegate void MarkerCallback(uint inst_id, uint marker_id, float marker_time, void* user_data); // iam_marker_callback + public delegate float EaseFn(float t); // iam_ease_fn + + public delegate float FloatResolver(void* user_data); // iam_float_resolver + public delegate Vector2 Vec2Resolver(void* user_data); // iam_vec2_resolver + public delegate Vector4 Vec4Resolver(void* user_data); // iam_vec4_resolver + public delegate int IntResolver(void* user_data); // iam_int_resolver + + public delegate float VariationFloatFn(int index, void* user_data); // iam_variation_float_fn + public delegate int VariationIntFn(int index, void* user_data); // iam_variation_int_fn + public delegate Vector2 VariationVec2Fn(int index, void* user_data); // iam_variation_vec2_fn + public delegate Vector4 VariationVec4Fn(int index, void* user_data); // iam_variation_vec4_fn + + // ---------------------------------------------------- + // Public API declarations + // ---------------------------------------------------- + + public static void SetImGuiContext(ImGuiContext* context) + { + ImAnimNative.SetImGuiContext(context); + } + + public static void DemoWindow() + { + ImAnimNative.DemoWindow(); + } + + // Frame management + + public static void UpdateBeginFrame() + { + ImAnimNative.UpdateBeginFrame(); + } + + public static void Gc(uint maxAgeFrames = 600) + { + ImAnimNative.Gc(maxAgeFrames); + } + + public static void Reserve(int capFloat, int capVec2, int capVec4, int capInt, int capColor) + { + ImAnimNative.Reserve(capFloat, capVec2, capVec4, capInt, capColor); + } + + public static void SetEaseLutSamples(int count) + { + ImAnimNative.SetEaseLutSamples(count); + } + + // Global time scale (for slow-motion / fast-forward debugging) + + public static void SetGlobalTimeScale(float scale) + { + ImAnimNative.SetGlobalTimeScale(scale); + } + + public static float GetGlobalTimeScale() + { + return ImAnimNative.GetGlobalTimeScale(); + } + + // Lazy Initialization - defer channel creation until animation is needed + + public static void SetLazyInit(bool enable) + { + ImAnimNative.SetLazyInit((byte)(enable ? 1 : 0)); + } + + public static byte IsLazyInitEnabled() + { + return ImAnimNative.IsLazyInitEnabled(); + } + + public static void RegisterCustomEase(int slot, EaseFn fn) + { + ImAnimNative.RegisterCustomEase(slot, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn)); + } + + public static EaseFn? GetCustomEase(int slot) + { + delegate* unmanaged[Cdecl] retFn = default; + ImAnimNative.GetCustomEase(&retFn, slot); + return retFn == null ? null : Marshal.GetDelegateForFunctionPointer((nint)retFn); + } + + // Debug UI + + public static void ShowUnifiedInspector() + { + ImAnimNative.ShowUnifiedInspector(); + } + + public static void ShowUnifiedInspector(ref bool pOpen) + { + var open = (byte)(pOpen ? 1 : 0); + ImAnimNative.ShowUnifiedInspector(&open); + pOpen = open == 1; + } + + // Performance Profiler + + public static void ProfilerEnable(bool enable) + { + ImAnimNative.ProfilerEnable((byte)(enable ? 1 : 0)); + } + + public static byte ProfilerIsEnabled() + { + return ImAnimNative.ProfilerIsEnabled(); + } + + public static void ProfilerBeginFrame() + { + ImAnimNative.ProfilerBeginFrame(); + } + + public static void ProfilerEndFrame() + { + ImAnimNative.ProfilerEndFrame(); + } + + public static void ProfilerBegin(ImU8String name) + { + fixed (byte* namePtr = &name.GetPinnableNullTerminatedReference()) + ImAnimNative.ProfilerBegin(namePtr); + name.Recycle(); + } + + public static void ProfilerEnd() + { + ImAnimNative.ProfilerEnd(); + } + + // Drag Feedback - animated feedback for drag operations + + public static ImAnimDragFeedback DragBegin(uint id, Vector2 pos) + { + ImAnimDragFeedback ret = default; + ImAnimNative.DragBegin(&ret, id, &pos); + return ret; + } + + public static ImAnimDragFeedback DragUpdate(uint id, Vector2 pos, float dt) + { + ImAnimDragFeedback ret = default; + ImAnimNative.DragUpdate(&ret, id, &pos, dt); + return ret; + } + + public static ImAnimDragFeedback DragRelease(uint id, Vector2 pos, ImAnimDragOpts opts, float dt) + { + ImAnimDragFeedback ret = default; + ImAnimNative.DragRelease(&ret, id, &pos, &opts, dt); + return ret; + } + + public static void DragCancel(uint id) + { + ImAnimNative.DragCancel(id); + } + + // Oscillators - continuous periodic animations + + public static float Oscillate(uint id, float amplitude, float frequency, ImAnimWaveType waveType, float phase, float dt) + { + return ImAnimNative.Oscillate(id, amplitude, frequency, waveType, phase, dt); + } + + public static int OscillateInt(uint id, int amplitude, float frequency, ImAnimWaveType waveType, float phase, float dt) + { + return ImAnimNative.OscillateInt(id, amplitude, frequency, waveType, phase, dt); + } + + public static Vector2 OscillateVec2(uint id, Vector2 amplitude, Vector2 frequency, ImAnimWaveType waveType, Vector2 phase, float dt) + { + Vector2 ret = default; + ImAnimNative.OscillateVec2(&ret, id, &litude, &frequency, waveType, &phase, dt); + return ret; + } + + public static Vector4 OscillateVec4(uint id, Vector4 amplitude, Vector4 frequency, ImAnimWaveType waveType, Vector4 phase, float dt) + { + Vector4 ret = default; + ImAnimNative.OscillateVec4(&ret, id, &litude, &frequency, waveType, &phase, dt); + return ret; + } + + public static Vector4 OscillateColor(uint id, Vector4 baseColor, Vector4 amplitude, float frequency, ImAnimWaveType waveType, float phase, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.OscillateColor(&ret, id, &baseColor, &litude, frequency, waveType, phase, colorSpace, dt); + return ret; + } + + // Shake/Wiggle - procedural noise animations + + public static float Shake(uint id, float intensity, float frequency, float decayTime, float dt) + { + return ImAnimNative.Shake(id, intensity, frequency, decayTime, dt); + } + + public static int ShakeInt(uint id, int intensity, float frequency, float decayTime, float dt) + { + return ImAnimNative.ShakeInt(id, intensity, frequency, decayTime, dt); + } + + public static Vector2 ShakeVec2(uint id, Vector2 intensity, float frequency, float decayTime, float dt) + { + Vector2 ret = default; + ImAnimNative.ShakeVec2(&ret, id, &intensity, frequency, decayTime, dt); + return ret; + } + + public static Vector4 ShakeVec4(uint id, Vector4 intensity, float frequency, float decayTime, float dt) + { + Vector4 ret = default; + ImAnimNative.ShakeVec4(&ret, id, &intensity, frequency, decayTime, dt); + return ret; + } + + public static Vector4 ShakeColor(uint id, Vector4 baseColor, Vector4 intensity, float frequency, float decayTime, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.ShakeColor(&ret, id, &baseColor, &intensity, frequency, decayTime, colorSpace, dt); + return ret; + } + + public static float Wiggle(uint id, float amplitude, float frequency, float dt) + { + return ImAnimNative.Wiggle(id, amplitude, frequency, dt); + } + + public static int WiggleInt(uint id, int amplitude, float frequency, float dt) + { + return ImAnimNative.WiggleInt(id, amplitude, frequency, dt); + } + + public static Vector2 WiggleVec2(uint id, Vector2 amplitude, float frequency, float dt) + { + Vector2 ret = default; + ImAnimNative.WiggleVec2(&ret, id, &litude, frequency, dt); + return ret; + } + + public static Vector4 WiggleVec4(uint id, Vector4 amplitude, float frequency, float dt) + { + Vector4 ret = default; + ImAnimNative.WiggleVec4(&ret, id, &litude, frequency, dt); + return ret; + } + + public static Vector4 WiggleColor(uint id, Vector4 baseColor, Vector4 amplitude, float frequency, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.WiggleColor(&ret, id, &baseColor, &litude, frequency, colorSpace, dt); + return ret; + } + + public static void TriggerShake(uint id) + { + ImAnimNative.TriggerShake(id); + } + + // Easing evaluation + + public static float EvalPreset(ImAnimEaseType type, float t) + { + return ImAnimNative.EvalPreset(type, t); + } + + // Tween API - smoothly interpolate values over time + + public static float TweenFloat(uint id, uint channelId, float target, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + return ImAnimNative.TweenFloat(id, channelId, target, dur, &ez, policy, dt); + } + + public static Vector2 TweenVec2(uint id, uint channelId, Vector2 target, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + Vector2 ret = default; + ImAnimNative.TweenVec2(&ret, id, channelId, &target, dur, &ez, policy, dt); + return ret; + } + + public static Vector4 TweenVec4(uint id, uint channelId, Vector4 target, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenVec4(&ret, id, channelId, &target, dur, &ez, policy, dt); + return ret; + } + + public static int TweenInt(uint id, uint channelId, int target, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + return ImAnimNative.TweenInt(id, channelId, target, dur, &ez, policy, dt); + } + + public static Vector4 TweenColor(uint id, uint channelId, Vector4 targetSrgb, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenColor(&ret, id, channelId, &targetSrgb, dur, &ez, policy, colorSpace, dt); + return ret; + } + + // Resize-friendly helpers + + public static Vector2 GetAnchorSize(ImAnimAnchorSpace space) + { + Vector2 ret = default; + ImAnimNative.GetAnchorSize(&ret, space); + return ret; + } + + // Relative target tweens (percent of anchor + pixel offset) - survive window resizes + + public static float TweenFloatRel(uint id, uint channelId, float percent, float pxBias, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimAnchorSpace anchorSpace, int axis, float dt) + { + return ImAnimNative.TweenFloatRel(id, channelId, percent, pxBias, dur, &ez, policy, anchorSpace, axis, dt); + } + + public static Vector2 TweenVec2Rel(uint id, uint channelId, Vector2 percent, Vector2 pxBias, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimAnchorSpace anchorSpace, float dt) + { + Vector2 ret = default; + ImAnimNative.TweenVec2Rel(&ret, id, channelId, &percent, &pxBias, dur, &ez, policy, anchorSpace, dt); + return ret; + } + + public static Vector4 TweenVec4Rel(uint id, uint channelId, Vector4 percent, Vector4 pxBias, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimAnchorSpace anchorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenVec4Rel(&ret, id, channelId, &percent, &pxBias, dur, &ez, policy, anchorSpace, dt); + return ret; + } + + public static Vector4 TweenColorRel(uint id, uint channelId, Vector4 percent, Vector4 pxBias, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, ImAnimAnchorSpace anchorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenColorRel(&ret, id, channelId, &percent, &pxBias, dur, &ez, policy, colorSpace, anchorSpace, dt); + return ret; + } + + // Rebase functions - change target of in-progress animation without restarting + + public static void RebaseFloat(uint id, uint channelId, float newTarget, float dt) + { + ImAnimNative.RebaseFloat(id, channelId, newTarget, dt); + } + + public static void RebaseVec2(uint id, uint channelId, Vector2 newTarget, float dt) + { + ImAnimNative.RebaseVec2(id, channelId, &newTarget, dt); + } + + public static void RebaseVec4(uint id, uint channelId, Vector4 newTarget, float dt) + { + ImAnimNative.RebaseVec4(id, channelId, &newTarget, dt); + } + + public static void RebaseInt(uint id, uint channelId, int newTarget, float dt) + { + ImAnimNative.RebaseInt(id, channelId, newTarget, dt); + } + + public static void RebaseColor(uint id, uint channelId, Vector4 newTarget, float dt) + { + ImAnimNative.RebaseColor(id, channelId, &newTarget, dt); + } + + // Resolved tweens - target computed dynamically by callback each frame + + public static float TweenFloatResolved(uint id, uint channelId, Func fn, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + float callback(void* user_data) => fn(); + return ImAnimNative.TweenFloatResolved(id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(callback), null, dur, &ez, policy, dt); + } + + public static float TweenFloatResolved(uint id, uint channelId, FloatResolver fn, void* user_data, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + return ImAnimNative.TweenFloatResolved(id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), user_data, dur, &ez, policy, dt); + } + + public static Vector2 TweenVec2Resolved(uint id, uint channelId, Func fn, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + Vector2 callback(void* user_data) => fn(); + Vector2 ret = default; + ImAnimNative.TweenVec2Resolved(&ret, id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(callback), null, dur, &ez, policy, dt); + return ret; + } + + public static Vector2 TweenVec2Resolved(uint id, uint channelId, Vec2Resolver fn, void* user_data, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + Vector2 ret = default; + ImAnimNative.TweenVec2Resolved(&ret, id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), user_data, dur, &ez, policy, dt); + return ret; + } + + public static Vector4 TweenVec4Resolved(uint id, uint channelId, Func fn, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + Vector4 callback(void* user_data) => fn(); + Vector4 ret = default; + ImAnimNative.TweenVec4Resolved(&ret, id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(callback), null, dur, &ez, policy, dt); + return ret; + } + + public static Vector4 TweenVec4Resolved(uint id, uint channelId, Vec4Resolver fn, void* user_data, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenVec4Resolved(&ret, id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), user_data, dur, &ez, policy, dt); + return ret; + } + + public static Vector4 TweenColorResolved(uint id, uint channelId, Func fn, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt) + { + Vector4 callback(void* user_data) => fn(); + Vector4 ret = default; + ImAnimNative.TweenColorResolved(&ret, id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(callback), null, dur, &ez, policy, colorSpace, dt); + return ret; + } + + public static Vector4 TweenColorResolved(uint id, uint channelId, Vec4Resolver fn, void* user_data, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenColorResolved(&ret, id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), user_data, dur, &ez, policy, colorSpace, dt); + return ret; + } + + public static int TweenIntResolved(uint id, uint channelId, Func fn, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + int callback(void* user_data) => fn(); + return ImAnimNative.TweenIntResolved(id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(callback), null, dur, &ez, policy, dt); + } + + public static int TweenIntResolved(uint id, uint channelId, IntResolver fn, void* user_data, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt) + { + return ImAnimNative.TweenIntResolved(id, channelId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), user_data, dur, &ez, policy, dt); + } + + // Color blending utility + + public static Vector4 GetBlendedColor(Vector4 a, Vector4 b, float t, ImAnimColorSpace colorSpace) + { + Vector4 ret = default; + ImAnimNative.GetBlendedColor(&ret, &a, &b, t, colorSpace); + return ret; + } + + + // ---------------------------------------------------- + // Convenience shorthands for common easings + // ---------------------------------------------------- + + public static ImAnimEaseDesc EasePreset(ImAnimEaseType type) + { + ImAnimEaseDesc ret = default; + ImAnimNative.EasePreset(&ret, type); + return ret; + } + + public static ImAnimEaseDesc EaseBezier(float x1, float y1, float x2, float y2) + { + ImAnimEaseDesc ret = default; + ImAnimNative.EaseBezier(&ret, x1, y1, x2, y2); + return ret; + } + + public static ImAnimEaseDesc EaseStepsDesc(int steps, ImAnimEaseStepsMode mode) + { + ImAnimEaseDesc ret = default; + ImAnimNative.EaseStepsDesc(&ret, steps, mode); + return ret; + } + + public static ImAnimEaseDesc EaseBack(float overshoot) + { + ImAnimEaseDesc ret = default; + ImAnimNative.EaseBack(&ret, overshoot); + return ret; + } + + public static ImAnimEaseDesc EaseElastic(float amplitude, float period) + { + ImAnimEaseDesc ret = default; + ImAnimNative.EaseElastic(&ret, amplitude, period); + return ret; + } + + public static ImAnimEaseDesc EaseSpring(float mass, float stiffness, float damping, float v0) + { + ImAnimEaseDesc ret = default; + ImAnimNative.EaseSpring(&ret, mass, stiffness, damping, v0); + return ret; + } + + public static ImAnimEaseDesc EaseCustomFn(int slot) + { + ImAnimEaseDesc ret = default; + ImAnimNative.EaseCustomFn(&ret, slot); + return ret; + } + + // Scroll animation - smooth scrolling for ImGui windows + + public static void ScrollToY(float targetY, float duration) + { + ImAnimNative.ScrollToY(targetY, duration, null); + } + + public static void ScrollToY(float targetY, float duration, ImAnimEaseDesc ez) + { + ImAnimNative.ScrollToY(targetY, duration, &ez); + } + + public static void ScrollToX(float targetX, float duration) + { + ImAnimNative.ScrollToX(targetX, duration, null); + } + + public static void ScrollToX(float targetX, float duration, ImAnimEaseDesc ez) + { + ImAnimNative.ScrollToX(targetX, duration, &ez); + } + + public static void ScrollToTop(float duration = 0.3f) + { + ImAnimNative.ScrollToTop(duration, null); + } + + public static void ScrollToTop(float duration, ImAnimEaseDesc ez) + { + ImAnimNative.ScrollToTop(duration, &ez); + } + + public static void ScrollToBottom(float duration = 0.3f) + { + ImAnimNative.ScrollToBottom(duration, null); + } + + public static void ScrollToBottom(float duration, ImAnimEaseDesc ez) + { + ImAnimNative.ScrollToBottom(duration, &ez); + } + + + // ---------------------------------------------------- + // Per-axis easing - different easing per component + // ---------------------------------------------------- + + // Tween with per-axis easing - each component uses its own easing curve + + public static Vector2 TweenVec2PerAxis(uint id, uint channelId, Vector2 target, float dur, ImAnimEasePerAxis ez, ImAnimPolicy policy, float dt) + { + Vector2 ret = default; + ImAnimNative.TweenVec2PerAxis(&ret, id, channelId, &target, dur, &ez, policy, dt); + return ret; + } + + public static Vector4 TweenVec4PerAxis(uint id, uint channelId, Vector4 target, float dur, ImAnimEasePerAxis ez, ImAnimPolicy policy, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenVec4PerAxis(&ret, id, channelId, &target, dur, &ez, policy, dt); + return ret; + } + + public static Vector4 TweenColorPerAxis(uint id, uint channelId, Vector4 targetSrgb, float dur, ImAnimEasePerAxis ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.TweenColorPerAxis(&ret, id, channelId, &targetSrgb, dur, &ez, policy, colorSpace, dt); + return ret; + } + + + // ---------------------------------------------------- + // Motion Paths - animate along curves and splines + // ---------------------------------------------------- + + // Single-curve evaluation functions (stateless, for direct use) + + public static Vector2 BezierQuadratic(Vector2 p0, Vector2 p1, Vector2 p2, float t) + { + Vector2 ret = default; + ImAnimNative.BezierQuadratic(&ret, &p0, &p1, &p2, t); + return ret; + } + + public static Vector2 BezierCubic(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t) + { + Vector2 ret = default; + ImAnimNative.BezierCubic(&ret, &p0, &p1, &p2, &p3, t); + return ret; + } + + public static Vector2 CatmullRom(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t, float tension) + { + Vector2 ret = default; + ImAnimNative.CatmullRom(&ret, &p0, &p1, &p2, &p3, t, tension); + return ret; + } + + // Derivatives (for tangent/velocity) + + public static Vector2 BezierQuadraticDeriv(Vector2 p0, Vector2 p1, Vector2 p2, float t) + { + Vector2 ret = default; + ImAnimNative.BezierQuadraticDeriv(&ret, &p0, &p1, &p2, t); + return ret; + } + + public static Vector2 BezierCubicDeriv(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t) + { + Vector2 ret = default; + ImAnimNative.BezierCubicDeriv(&ret, &p0, &p1, &p2, &p3, t); + return ret; + } + + public static Vector2 CatmullRomDeriv(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t, float tension) + { + Vector2 ret = default; + ImAnimNative.CatmullRomDeriv(&ret, &p0, &p1, &p2, &p3, t, tension); + return ret; + } + + // Query path info + + public static bool PathExists(uint pathId) + { + return ImAnimNative.PathExists(pathId) == 1; + } + + public static float PathLength(uint pathId) + { + return ImAnimNative.PathLength(pathId); + } + + public static Vector2 PathEvaluate(uint pathId, float t) + { + Vector2 ret = default; + ImAnimNative.PathEvaluate(&ret, pathId, t); + return ret; + } + + public static Vector2 PathTangent(uint pathId, float t) + { + Vector2 ret = default; + ImAnimNative.PathTangent(&ret, pathId, t); + return ret; + } + + public static float PathAngle(uint pathId, float t) + { + return ImAnimNative.PathAngle(pathId, t); + } + + // Tween along a path + + public static Vector2 TweenPath(uint id, uint channelId, uint pathId, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt = -1f) + { + Vector2 ret = default; + ImAnimNative.TweenPath(&ret, id, channelId, pathId, dur, &ez, policy, dt); + return ret; + } + + public static float TweenPathAngle(uint id, uint channelId, uint pathId, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, float dt = -1f) + { + return ImAnimNative.TweenPathAngle(id, channelId, pathId, dur, &ez, policy, dt); + } + + + // ---------------------------------------------------- + // Arc-length parameterization (for constant-speed animation) + // ---------------------------------------------------- + + // Build arc-length lookup table for a path (call once per path, improves accuracy) + + public static void PathBuildArcLut(uint pathId, int subdivisions) + { + ImAnimNative.PathBuildArcLut(pathId, subdivisions); + } + + public static bool PathHasArcLut(uint pathId) + { + return ImAnimNative.PathHasArcLut(pathId) == 1; + } + + // Distance-based path evaluation (uses arc-length LUT for constant speed) + + public static float PathDistanceToT(uint pathId, float distance) + { + return ImAnimNative.PathDistanceToT(pathId, distance); + } + + public static Vector2 PathEvaluateAtDistance(uint pathId, float distance) + { + Vector2 ret = default; + ImAnimNative.PathEvaluateAtDistance(&ret, pathId, distance); + return ret; + } + + public static float PathAngleAtDistance(uint pathId, float distance) + { + return ImAnimNative.PathAngleAtDistance(pathId, distance); + } + + public static Vector2 PathTangentAtDistance(uint pathId, float distance) + { + Vector2 ret = default; + ImAnimNative.PathTangentAtDistance(&ret, pathId, distance); + return ret; + } + + + // ---------------------------------------------------- + // Path Morphing - interpolate between two paths + // ---------------------------------------------------- + + // Evaluate morphed path at parameter t [0,1] with blend factor [0,1] + // path_a at blend=0, path_b at blend=1 + // Paths can have different numbers of segments - they are resampled to match + public static Vector2 PathMorph(uint pathA, uint pathB, float t, float blend) + { + Vector2 ret = default; + ImAnimNative.PathMorph(&ret, pathA, pathB, t, blend, null); + return ret; + } + public static Vector2 PathMorph(uint pathA, uint pathB, float t, float blend, ImAnimMorphOpts opts) + { + Vector2 ret = default; + ImAnimNative.PathMorph(&ret, pathA, pathB, t, blend, &opts); + return ret; + } + + // Get tangent of morphed path + public static Vector2 PathMorphTangent(uint pathA, uint pathB, float t, float blend) + { + Vector2 ret = default; + ImAnimNative.PathMorphTangent(&ret, pathA, pathB, t, blend, null); + return ret; + } + public static Vector2 PathMorphTangent(uint pathA, uint pathB, float t, float blend, ImAnimMorphOpts opts) + { + Vector2 ret = default; + ImAnimNative.PathMorphTangent(&ret, pathA, pathB, t, blend, &opts); + return ret; + } + + // Get angle (radians) of morphed path + public static float PathMorphAngle(uint pathA, uint pathB, float t, float blend) + { + return ImAnimNative.PathMorphAngle(pathA, pathB, t, blend, null); + } + public static float PathMorphAngle(uint pathA, uint pathB, float t, float blend, ImAnimMorphOpts opts) + { + return ImAnimNative.PathMorphAngle(pathA, pathB, t, blend, &opts); + } + + // Tween along a morphing path - animates both position along path AND the morph blend + public static Vector2 TweenPathMorph(uint id, uint channelId, uint pathA, uint pathB, float targetBlend, float dur, ImAnimEaseDesc pathEase, ImAnimEaseDesc morphEase, ImAnimPolicy policy, float dt) + { + Vector2 ret = default; + ImAnimNative.TweenPathMorph(&ret, id, channelId, pathA, pathB, targetBlend, dur, &pathEase, &morphEase, policy, dt, null); + return ret; + } + public static Vector2 TweenPathMorph(uint id, uint channelId, uint pathA, uint pathB, float targetBlend, float dur, ImAnimEaseDesc pathEase, ImAnimEaseDesc morphEase, ImAnimPolicy policy, float dt, ImAnimMorphOpts opts) + { + Vector2 ret = default; + ImAnimNative.TweenPathMorph(&ret, id, channelId, pathA, pathB, targetBlend, dur, &pathEase, &morphEase, policy, dt, &opts); + return ret; + } + + // Get current morph blend value from a tween (for querying state) + public static float GetMorphBlend(uint id, uint channelId) + { + return ImAnimNative.GetMorphBlend(id, channelId); + } + + + // ---------------------------------------------------- + // Text along motion paths + // ---------------------------------------------------- + + // Render text along a path (static - no animation) + public static void TextPath(uint pathId, ImU8String text) + { + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ImAnimNative.TextPath(pathId, textPtr, null); + text.Recycle(); + } + public static void TextPath(uint pathId, ImU8String text, ImAnimTextPathOpts opts) + { + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ImAnimNative.TextPath(pathId, textPtr, &opts); + text.Recycle(); + } + + // Animated text along path (characters appear progressively) + public static void TextPathAnimated(uint pathId, ImU8String text, float progress) + { + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ImAnimNative.TextPathAnimated(pathId, textPtr, progress, null); + text.Recycle(); + } + public static void TextPathAnimated(uint pathId, ImU8String text, float progress, ImAnimTextPathOpts opts) + { + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ImAnimNative.TextPathAnimated(pathId, textPtr, progress, &opts); + text.Recycle(); + } + + // Helper: Get text width for path layout calculations + public static float TextPathWidth(ImU8String text) + { + float ret = default; + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ret = ImAnimNative.TextPathWidth(textPtr, null); + text.Recycle(); + return ret; + } + public static float TextPathWidth(ImU8String text, ImAnimTextPathOpts opts) + { + float ret = default; + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ret = ImAnimNative.TextPathWidth(textPtr, &opts); + text.Recycle(); + return ret; + } + + + // ---------------------------------------------------- + // Quad transform helpers (for advanced custom rendering) + // ---------------------------------------------------- + + // Transform a quad (4 vertices) by rotation and translation + public static void TransformQuad(ref Quaternion quad, Vector2 center, float angleRad, Vector2 translation) + { + ImAnimNative.TransformQuad((Quaternion*)Unsafe.AsPointer(ref quad), ¢er, angleRad, &translation); + } + + // Create a rotated quad for a glyph at a position on the path + public static void MakeGlyphQuad(ref Quaternion quad, Vector2 pos, float angleRad, float glyphWidth, float glyphHeight, float baselineOffset) + { + ImAnimNative.MakeGlyphQuad((Quaternion*)Unsafe.AsPointer(ref quad), &pos, angleRad, glyphWidth, glyphHeight, baselineOffset); + } + + + // ---------------------------------------------------- + // Text Stagger - per-character animation effects + // ---------------------------------------------------- + + // Render text with per-character stagger animation + public static void TextStagger(uint id, ImU8String text, float progress) + { + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ImAnimNative.TextStagger(id, textPtr, progress, null); + text.Recycle(); + } + public static void TextStagger(uint id, ImU8String text, float progress, ImAnimTextStaggerOpts opts) + { + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ImAnimNative.TextStagger(id, textPtr, progress, &opts); + text.Recycle(); + } + + // Get text width for layout calculations + public static float TextStaggerWidth(ImU8String text) + { + float ret = default; + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ret = ImAnimNative.TextStaggerWidth(textPtr, null); + text.Recycle(); + return ret; + } + public static float TextStaggerWidth(ImU8String text, ImAnimTextStaggerOpts opts) + { + float ret = default; + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ret = ImAnimNative.TextStaggerWidth(textPtr, &opts); + text.Recycle(); + return ret; + } + + // Get total animation duration for text (accounts for stagger delays) + public static float TextStaggerDuration(ImU8String text) + { + float ret = default; + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ret = ImAnimNative.TextStaggerDuration(textPtr, null); + text.Recycle(); + return ret; + } + public static float TextStaggerDuration(ImU8String text, ImAnimTextStaggerOpts opts) + { + float ret = default; + fixed (byte* textPtr = &text.GetPinnableNullTerminatedReference()) + ret = ImAnimNative.TextStaggerDuration(textPtr, &opts); + text.Recycle(); + return ret; + } + + + // ---------------------------------------------------- + // Noise Channels - Perlin/Simplex noise for organic movement + // ---------------------------------------------------- + + // Sample noise at a point (returns value in [-1, 1]) + + public static float Noise2D(float x, float y) + { + return ImAnimNative.Noise2D(x, y, null); + } + public static float Noise2D(float x, float y, ImAnimNoiseOpts opts) + { + return ImAnimNative.Noise2D(x, y, &opts); + } + + public static float Noise3D(float x, float y, float z) + { + return ImAnimNative.Noise3D(x, y, z, null); + } + public static float Noise3D(float x, float y, float z, ImAnimNoiseOpts opts) + { + return ImAnimNative.Noise3D(x, y, z, &opts); + } + + // Animated noise channels - continuous noise that evolves over time + + public static float NoiseChannelFloat(uint id, float frequency, float amplitude, ImAnimNoiseOpts opts, float dt) + { + return ImAnimNative.NoiseChannelFloat(id, frequency, amplitude, &opts, dt); + } + + public static Vector2 NoiseChannelVec2(uint id, Vector2 frequency, Vector2 amplitude, ImAnimNoiseOpts opts, float dt) + { + Vector2 ret = default; + ImAnimNative.NoiseChannelVec2(&ret, id, &frequency, &litude, &opts, dt); + return ret; + } + + public static Vector4 NoiseChannelVec4(uint id, Vector4 frequency, Vector4 amplitude, ImAnimNoiseOpts opts, float dt) + { + Vector4 ret = default; + ImAnimNative.NoiseChannelVec4(&ret, id, &frequency, &litude, &opts, dt); + return ret; + } + + public static Vector4 NoiseChannelColor(uint id, Vector4 baseColor, Vector4 amplitude, float frequency, ImAnimNoiseOpts opts, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.NoiseChannelColor(&ret, id, &baseColor, &litude, frequency, &opts, colorSpace, dt); + return ret; + } + + // Convenience: smooth random movement (like wiggle but using noise) + + public static float SmoothNoiseFloat(uint id, float amplitude, float speed, float dt) + { + return ImAnimNative.SmoothNoiseFloat(id, amplitude, speed, dt); + } + + public static Vector2 SmoothNoiseVec2(uint id, Vector2 amplitude, float speed, float dt) + { + Vector2 ret = default; + ImAnimNative.SmoothNoiseVec2(&ret, id, &litude, speed, dt); + return ret; + } + + public static Vector4 SmoothNoiseVec4(uint id, Vector4 amplitude, float speed, float dt) + { + Vector4 ret = default; + ImAnimNative.SmoothNoiseVec4(&ret, id, &litude, speed, dt); + return ret; + } + + public static Vector4 SmoothNoiseColor(uint id, Vector4 baseColor, Vector4 amplitude, float speed, ImAnimColorSpace colorSpace, float dt) + { + Vector4 ret = default; + ImAnimNative.SmoothNoiseColor(&ret, id, &baseColor, &litude, speed, colorSpace, dt); + return ret; + } + + + // ---------------------------------------------------- + // Style Interpolation - animate between ImGuiStyle themes + // ---------------------------------------------------- + + // Register a named style for interpolation + public static void StyleRegister(uint styleId, ImGuiStylePtr style) + { + ImAnimNative.StyleRegister(styleId, style); + } + + public static void StyleRegisterCurrent(uint styleId) + { + ImAnimNative.StyleRegisterCurrent(styleId); + } + + // Blend between two registered styles (result applied to ImGui::GetStyle()) + // Uses iam_color_space for color blending mode (iam_col_oklab recommended) + public static void StyleBlend(uint styleA, uint styleB, float t, ImAnimColorSpace colorSpace = ImAnimColorSpace.Oklab) + { + ImAnimNative.StyleBlend(styleA, styleB, t, colorSpace); + } + + // Tween between styles over time + public static void StyleTween(uint id, uint targetStyle, float duration, ImAnimEaseDesc ease, ImAnimColorSpace colorSpace, float dt) + { + ImAnimNative.StyleTween(id, targetStyle, duration, &ease, colorSpace, dt); + } + + // Get interpolated style without applying + public static ImGuiStyle StyleBlendTo(uint styleA, uint styleB, float t, ImAnimColorSpace colorSpace = ImAnimColorSpace.Oklab) + { + ImGuiStyle ret = default; + ImAnimNative.StyleBlendTo(styleA, styleB, t, &ret, colorSpace); + return ret; + } + + // Check if a style is registered + public static bool StyleExists(uint styleId) + { + return ImAnimNative.StyleExists(styleId) == 1; + } + + // Remove a registered style + public static void StyleUnregister(uint styleId) + { + ImAnimNative.StyleUnregister(styleId); + } + + + // ---------------------------------------------------- + // Gradient Interpolation - animate between color gradients + // ---------------------------------------------------- + + // Blend between two gradients + public static ImAnimGradient GradientLerp(ImAnimGradient a, ImAnimGradient b, float t, ImAnimColorSpace colorSpace = ImAnimColorSpace.Oklab) + { + ImAnimGradient ret = default; + ImAnimNative.GradientLerp(&ret, &a, &b, t, colorSpace); + return ret; + } + + public static ImAnimGradient TweenGradient(uint id, uint channelId, ImAnimGradient target, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt) + { + ImAnimGradient ret = default; + ImAnimNative.TweenGradient(&ret, id, channelId, &target, dur, &ez, policy, colorSpace, dt); + return ret; + } + + + // ---------------------------------------------------- + // Transform Interpolation - animate 2D transforms + // ---------------------------------------------------- + + // Blend between two transforms with rotation interpolation + public static ImAnimTransform TransformLerp(ImAnimTransform a, ImAnimTransform b, float t, ImAnimRotationMode rotationMode = ImAnimRotationMode.Shortest) + { + ImAnimTransform ret = default; + ImAnimNative.TransformLerp(&ret, &a, &b, t, rotationMode); + return ret; + } + + /// Tween between transforms over time + public static ImAnimTransform TweenTransform(uint id, uint channelId, ImAnimTransform target, float dur, ImAnimEaseDesc ez, ImAnimPolicy policy, int rotationMode, float dt) + { + ImAnimTransform ret = default; + ImAnimNative.TweenTransform(&ret, id, channelId, &target, dur, &ez, policy, rotationMode, dt); + return ret; + } + + // Decompose a 3x2 matrix into transform components + public static ImAnimTransform TransformFromMatrix(Matrix3x2 matrix) + { + ImAnimTransform ret = default; + ImAnimNative.TransformFromMatrix(&ret, matrix.M11, matrix.M12, matrix.M21, matrix.M22, matrix.M31, matrix.M32); + return ret; + } + public static ImAnimTransform TransformFromMatrix(float m00, float m01, float m10, float m11, float tx, float ty) + { + ImAnimTransform ret = default; + ImAnimNative.TransformFromMatrix(&ret, m00, m01, m10, m11, tx, ty); + return ret; + } + + // Convert transform to 3x2 matrix (row-major: [m00 m01 tx; m10 m11 ty]) + public static Matrix3x2 TransformToMatrix(ImAnimTransform t) + { + Matrix3x2 ret = default; + ImAnimNative.TransformToMatrix(&t, &ret); + return ret; + } + + + // ---------------------------------------------------- + // iam_clip - fluent API for authoring animations + // ---------------------------------------------------- + + public static ImAnimClip ClipBegin(uint clipId) + { + ImAnimClip ret = default; + ImAnimNative.ClipBegin(&ret, clipId); + return ret; + } + + + // ---------------------------------------------------- + // Clip System API + // ---------------------------------------------------- + + // Initialize/shutdown (optional - auto-init on first use) + public static void ClipInit(int initialClipCap, int initialInstCap) + { + ImAnimNative.ClipInit(initialClipCap, initialInstCap); + } + + public static void ClipShutdown() + { + ImAnimNative.ClipShutdown(); + } + + // c_Per-frame update (call after iam_update_begin_frame) + public static void ClipUpdate(float dt) + { + ImAnimNative.ClipUpdate(dt); + } + + // Garbage collection for instances + public static void ClipGc(uint maxAgeFrames) + { + ImAnimNative.ClipGc(maxAgeFrames); + } + + // Play a clip on an instance (creates or reuses instance) + public static ImAnimInstance Play(uint clipId, uint instanceId) + { + ImAnimInstance ret = default; + ImAnimNative.Play(&ret, clipId, instanceId); + return ret; + } + + // Get an existing instance (returns invalid iam_instance if not found) + public static ImAnimInstance GetInstance(uint instanceId) + { + ImAnimInstance ret = default; + ImAnimNative.GetInstance(&ret, instanceId); + return ret; + } + + // Query clip info + public static float ClipDuration(uint clipId) + { + return ImAnimNative.ClipDuration(clipId); + } + + public static byte ClipExists(uint clipId) + { + return ImAnimNative.ClipExists(clipId); + } + + // Stagger helpers - compute delay for indexed instances + public static float StaggerDelay(uint clipId, int index) + { + return ImAnimNative.StaggerDelay(clipId, index); + } + + public static ImAnimInstance PlayStagger(uint clipId, uint instanceId, int index) + { + ImAnimInstance ret = default; + ImAnimNative.PlayStagger(&ret, clipId, instanceId, index); + return ret; + } + + // Layering support - blend multiple animation instances + public static void LayerBegin(uint instanceId) + { + ImAnimNative.LayerBegin(instanceId); + } + + public static void LayerAdd(ImAnimInstance* inst, float weight) // TODO: ref this? + { + ImAnimNative.LayerAdd(inst, weight); + } + + public static void LayerEnd(uint instanceId) + { + ImAnimNative.LayerEnd(instanceId); + } + + public static bool GetBlendedFloat(uint instanceId, uint channel, float* outVal) + { + return ImAnimNative.GetBlendedFloat(instanceId, channel, outVal) == 1; + } + + public static bool GetBlendedVec2(uint instanceId, uint channel, Vector2* outVal) + { + return ImAnimNative.GetBlendedVec2(instanceId, channel, outVal) == 1; + } + + public static bool GetBlendedVec4(uint instanceId, uint channel, Vector4* outVal) + { + return ImAnimNative.GetBlendedVec4(instanceId, channel, outVal) == 1; + } + + public static bool GetBlendedInt(uint instanceId, uint channel, int* outVal) + { + return ImAnimNative.GetBlendedInt(instanceId, channel, outVal) == 1; + } + + // Persistence (optional) + public static ImAnimResult ClipSave(uint clipId, ImU8String path) + { + ImAnimResult ret = default; + fixed (byte* pathPtr = &path.GetPinnableNullTerminatedReference()) + ret = ImAnimNative.ClipSave(clipId, pathPtr); + path.Recycle(); + return ret; + } + + public static ImAnimResult ClipLoad(ImU8String path, out uint clipId) + { + ImAnimResult ret = default; + fixed (byte* pathPtr = &path.GetPinnableNullTerminatedReference()) + fixed (uint* outClipId = &clipId) + ret = ImAnimNative.ClipLoad(pathPtr, outClipId); + path.Recycle(); + return ret; + } +} diff --git a/imgui/Dalamud.Bindings.ImAnim/ImAnimNative.cs b/imgui/Dalamud.Bindings.ImAnim/ImAnimNative.cs new file mode 100644 index 000000000..3d2c47b40 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/ImAnimNative.cs @@ -0,0 +1,809 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +using Dalamud.Bindings.ImGui; + +namespace Dalamud.Bindings.ImAnim; + +public static unsafe partial class ImAnimNative +{ + private const string LibName = "cimanim"; + + // ---------------------------------------------------- + // Public API declarations + // ---------------------------------------------------- + + [LibraryImport(LibName, EntryPoint = "c_iam_set_imgui_context")] + public static partial void SetImGuiContext(ImGuiContext* context); + + [LibraryImport(LibName, EntryPoint = "c_iam_demo_window")] + public static partial void DemoWindow(); + + // Frame management + + [LibraryImport(LibName, EntryPoint = "c_iam_update_begin_frame")] + public static partial void UpdateBeginFrame(); + + [LibraryImport(LibName, EntryPoint = "c_iam_gc")] + public static partial void Gc(uint maxAgeFrames = 600); + + [LibraryImport(LibName, EntryPoint = "c_iam_reserve")] + public static partial void Reserve(int capFloat, int capVec2, int capVec4, int capInt, int capColor); + + [LibraryImport(LibName, EntryPoint = "c_iam_set_ease_lut_samples")] + public static partial void SetEaseLutSamples(int count); + + // Global time scale (for slow-motion / fast-forward debugging) + + [LibraryImport(LibName, EntryPoint = "c_iam_set_global_time_scale")] + public static partial void SetGlobalTimeScale(float scale); + + [LibraryImport(LibName, EntryPoint = "c_iam_get_global_time_scale")] + public static partial float GetGlobalTimeScale(); + + // Lazy Initialization - defer channel creation until animation is needed + + [LibraryImport(LibName, EntryPoint = "c_iam_set_lazy_init")] + public static partial void SetLazyInit(byte enable); + + [LibraryImport(LibName, EntryPoint = "c_iam_is_lazy_init_enabled")] + public static partial byte IsLazyInitEnabled(); + + [LibraryImport(LibName, EntryPoint = "c_iam_register_custom_ease")] + public static partial void RegisterCustomEase(int slot, delegate* unmanaged[Cdecl] fn); + + [LibraryImport(LibName, EntryPoint = "c_iam_get_custom_ease")] + public static partial void GetCustomEase(delegate* unmanaged[Cdecl]* pOut, int slot); + + // Debug UI + + [LibraryImport(LibName, EntryPoint = "c_iam_show_unified_inspector")] + public static partial void ShowUnifiedInspector(byte* pOpen = null); + + // Performance Profiler + + [LibraryImport(LibName, EntryPoint = "c_iam_profiler_enable")] + public static partial void ProfilerEnable(byte enable); + + [LibraryImport(LibName, EntryPoint = "c_iam_profiler_is_enabled")] + public static partial byte ProfilerIsEnabled(); + + [LibraryImport(LibName, EntryPoint = "c_iam_profiler_begin_frame")] + public static partial void ProfilerBeginFrame(); + + [LibraryImport(LibName, EntryPoint = "c_iam_profiler_end_frame")] + public static partial void ProfilerEndFrame(); + + [LibraryImport(LibName, EntryPoint = "c_iam_profiler_begin")] + public static partial void ProfilerBegin(byte* name); + + [LibraryImport(LibName, EntryPoint = "c_iam_profiler_end")] + public static partial void ProfilerEnd(); + + // Drag Feedback - animated feedback for drag operations + + [LibraryImport(LibName, EntryPoint = "c_iam_drag_begin")] + public static partial void DragBegin(ImAnimDragFeedback* pOut, uint id, Vector2* pos); + + [LibraryImport(LibName, EntryPoint = "c_iam_drag_update")] + public static partial void DragUpdate(ImAnimDragFeedback* pOut, uint id, Vector2* pos, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_drag_release")] + public static partial void DragRelease(ImAnimDragFeedback* pOut, uint id, Vector2* pos, ImAnimDragOpts* opts, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_drag_cancel")] + public static partial void DragCancel(uint id); + + // Oscillators - continuous periodic animations + + [LibraryImport(LibName, EntryPoint = "c_iam_oscillate")] + public static partial float Oscillate(uint id, float amplitude, float frequency, ImAnimWaveType waveType, float phase, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_oscillate_int")] + public static partial int OscillateInt(uint id, int amplitude, float frequency, ImAnimWaveType waveType, float phase, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_oscillate_vec2")] + public static partial void OscillateVec2(Vector2* pOut, uint id, Vector2* amplitude, Vector2* frequency, ImAnimWaveType waveType, Vector2* phase, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_oscillate_vec4")] + public static partial void OscillateVec4(Vector4* pOut, uint id, Vector4* amplitude, Vector4* frequency, ImAnimWaveType waveType, Vector4* phase, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_oscillate_color")] + public static partial void OscillateColor(Vector4* pOut, uint id, Vector4* baseColor, Vector4* amplitude, float frequency, ImAnimWaveType waveType, float phase, ImAnimColorSpace colorSpace, float dt); + + // Shake/Wiggle - procedural noise animations + + [LibraryImport(LibName, EntryPoint = "c_iam_shake")] + public static partial float Shake(uint id, float intensity, float frequency, float decayTime, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_shake_int")] + public static partial int ShakeInt(uint id, int intensity, float frequency, float decayTime, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_shake_vec2")] + public static partial void ShakeVec2(Vector2* pOut, uint id, Vector2* intensity, float frequency, float decayTime, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_shake_vec4")] + public static partial void ShakeVec4(Vector4* pOut, uint id, Vector4* intensity, float frequency, float decayTime, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_shake_color")] + public static partial void ShakeColor(Vector4* pOut, uint id, Vector4* baseColor, Vector4* intensity, float frequency, float decayTime, ImAnimColorSpace colorSpace, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_wiggle")] + public static partial float Wiggle(uint id, float amplitude, float frequency, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_wiggle_int")] + public static partial int WiggleInt(uint id, int amplitude, float frequency, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_wiggle_vec2")] + public static partial void WiggleVec2(Vector2* pOut, uint id, Vector2* amplitude, float frequency, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_wiggle_vec4")] + public static partial void WiggleVec4(Vector4* pOut, uint id, Vector4* amplitude, float frequency, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_wiggle_color")] + public static partial void WiggleColor(Vector4* pOut, uint id, Vector4* baseColor, Vector4* amplitude, float frequency, ImAnimColorSpace colorSpace, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_trigger_shake")] + public static partial void TriggerShake(uint id); + + // Easing evaluation + + [LibraryImport(LibName, EntryPoint = "c_iam_eval_preset")] + public static partial float EvalPreset(ImAnimEaseType type, float t); + + // Tween API - smoothly interpolate values over time + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_float")] + public static partial float TweenFloat(uint id, uint channelId, float target, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec2")] + public static partial void TweenVec2(Vector2* pOut, uint id, uint channelId, Vector2* target, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec4")] + public static partial void TweenVec4(Vector4* pOut, uint id, uint channelId, Vector4* target, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_int")] + public static partial int TweenInt(uint id, uint channelId, int target, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_color")] + public static partial void TweenColor(Vector4* pOut, uint id, uint channelId, Vector4* targetSrgb, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt); + + // Resize-friendly helpers + + [LibraryImport(LibName, EntryPoint = "c_iam_anchor_size")] + public static partial void GetAnchorSize(Vector2* pOut, ImAnimAnchorSpace space); + + // Relative target tweens (percent of anchor + pixel offset) - survive window resizes + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_float_rel")] + public static partial float TweenFloatRel(uint id, uint channelId, float percent, float pxBias, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, ImAnimAnchorSpace anchorSpace, int axis, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec2_rel")] + public static partial void TweenVec2Rel(Vector2* pOut, uint id, uint channelId, Vector2* percent, Vector2* pxBias, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, ImAnimAnchorSpace anchorSpace, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec4_rel")] + public static partial void TweenVec4Rel(Vector4* pOut, uint id, uint channelId, Vector4* percent, Vector4* pxBias, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, ImAnimAnchorSpace anchorSpace, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_color_rel")] + public static partial void TweenColorRel(Vector4* pOut, uint id, uint channelId, Vector4* percent, Vector4* pxBias, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, ImAnimAnchorSpace anchorSpace, float dt); + + // Rebase functions - change target of in-progress animation without restarting + + [LibraryImport(LibName, EntryPoint = "c_iam_rebase_float")] + public static partial void RebaseFloat(uint id, uint channelId, float newTarget, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_rebase_vec2")] + public static partial void RebaseVec2(uint id, uint channelId, Vector2* newTarget, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_rebase_vec4")] + public static partial void RebaseVec4(uint id, uint channelId, Vector4* newTarget, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_rebase_int")] + public static partial void RebaseInt(uint id, uint channelId, int newTarget, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_rebase_color")] + public static partial void RebaseColor(uint id, uint channelId, Vector4* newTarget, float dt); + + // Resolved tweens - target computed dynamically by callback each frame + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_float_resolved")] + public static partial float TweenFloatResolved(uint id, uint channelId, delegate* unmanaged[Cdecl] fn, void* userData, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec2_resolved")] + public static partial void TweenVec2Resolved(Vector2* pOut, uint id, uint channelId, delegate* unmanaged[Cdecl] fn, void* userData, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec4_resolved")] + public static partial void TweenVec4Resolved(Vector4* pOut, uint id, uint channelId, delegate* unmanaged[Cdecl] fn, void* userData, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_color_resolved")] + public static partial void TweenColorResolved(Vector4* pOut, uint id, uint channelId, delegate* unmanaged[Cdecl] fn, void* userData, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_int_resolved")] + public static partial int TweenIntResolved(uint id, uint channelId, delegate* unmanaged[Cdecl] fn, void* userData, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt); + + // Color blending utility + + [LibraryImport(LibName, EntryPoint = "c_iam_get_blended_color")] + public static partial void GetBlendedColor(Vector4* pOut, Vector4* a, Vector4* b, float t, ImAnimColorSpace colorSpace); + + + // ---------------------------------------------------- + // Convenience shorthands for common easings + // ---------------------------------------------------- + + [LibraryImport(LibName, EntryPoint = "c_iam_ease_preset")] + public static partial void EasePreset(ImAnimEaseDesc* pOut, ImAnimEaseType type); + + [LibraryImport(LibName, EntryPoint = "c_iam_ease_bezier")] + public static partial void EaseBezier(ImAnimEaseDesc* pOut, float x1, float y1, float x2, float y2); + + [LibraryImport(LibName, EntryPoint = "c_iam_ease_steps_desc")] + public static partial void EaseStepsDesc(ImAnimEaseDesc* pOut, int steps, ImAnimEaseStepsMode mode); + + [LibraryImport(LibName, EntryPoint = "c_iam_ease_back")] + public static partial void EaseBack(ImAnimEaseDesc* pOut, float overshoot); + + [LibraryImport(LibName, EntryPoint = "c_iam_ease_elastic")] + public static partial void EaseElastic(ImAnimEaseDesc* pOut, float amplitude, float period); + + [LibraryImport(LibName, EntryPoint = "c_iam_ease_spring_desc")] + public static partial void EaseSpring(ImAnimEaseDesc* pOut, float mass, float stiffness, float damping, float v0); + + [LibraryImport(LibName, EntryPoint = "c_iam_ease_custom_fn")] + public static partial void EaseCustomFn(ImAnimEaseDesc* pOut, int slot); + + // Scroll animation - smooth scrolling for ImGui windows + + [LibraryImport(LibName, EntryPoint = "c_iam_scroll_to_y")] + public static partial void ScrollToY(float targetY, float duration, ImAnimEaseDesc* ez = null); + + [LibraryImport(LibName, EntryPoint = "c_iam_scroll_to_x")] + public static partial void ScrollToX(float targetX, float duration, ImAnimEaseDesc* ez = null); + + [LibraryImport(LibName, EntryPoint = "c_iam_scroll_to_top")] + public static partial void ScrollToTop(float duration = 0.3f, ImAnimEaseDesc* ez = null); + + [LibraryImport(LibName, EntryPoint = "c_iam_scroll_to_bottom")] + public static partial void ScrollToBottom(float duration = 0.3f, ImAnimEaseDesc* ez = null); + + + // ---------------------------------------------------- + // Per-axis easing - different easing per component + // ---------------------------------------------------- + + // Tween with per-axis easing - each component uses its own easing curve + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec2_per_axis")] + public static partial void TweenVec2PerAxis(Vector2* pOut, uint id, uint channelId, Vector2* target, float dur, ImAnimEasePerAxis* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_vec4_per_axis")] + public static partial void TweenVec4PerAxis(Vector4* pOut, uint id, uint channelId, Vector4* target, float dur, ImAnimEasePerAxis* ez, ImAnimPolicy policy, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_color_per_axis")] + public static partial void TweenColorPerAxis(Vector4* pOut, uint id, uint channelId, Vector4* targetSrgb, float dur, ImAnimEasePerAxis* ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt); + + + // ---------------------------------------------------- + // Motion Paths - animate along curves and splines + // ---------------------------------------------------- + + // Single-curve evaluation functions (stateless, for direct use) + + [LibraryImport(LibName, EntryPoint = "c_iam_bezier_quadratic")] + public static partial void BezierQuadratic(Vector2* pOut, Vector2* p0, Vector2* p1, Vector2* p2, float t); + + [LibraryImport(LibName, EntryPoint = "c_iam_bezier_cubic")] + public static partial void BezierCubic(Vector2* pOut, Vector2* p0, Vector2* p1, Vector2* p2, Vector2* p3, float t); + + [LibraryImport(LibName, EntryPoint = "c_iam_catmull_rom")] + public static partial void CatmullRom(Vector2* pOut, Vector2* p0, Vector2* p1, Vector2* p2, Vector2* p3, float t, float tension); + + // Derivatives (for tangent/velocity) + + [LibraryImport(LibName, EntryPoint = "c_iam_bezier_quadratic_deriv")] + public static partial void BezierQuadraticDeriv(Vector2* pOut, Vector2* p0, Vector2* p1, Vector2* p2, float t); + + [LibraryImport(LibName, EntryPoint = "c_iam_bezier_cubic_deriv")] + public static partial void BezierCubicDeriv(Vector2* pOut, Vector2* p0, Vector2* p1, Vector2* p2, Vector2* p3, float t); + + [LibraryImport(LibName, EntryPoint = "c_iam_catmull_rom_deriv")] + public static partial void CatmullRomDeriv(Vector2* pOut, Vector2* p0, Vector2* p1, Vector2* p2, Vector2* p3, float t, float tension); + + // Query path info + + [LibraryImport(LibName, EntryPoint = "c_iam_path_exists")] + public static partial byte PathExists(uint pathId); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_length")] + public static partial float PathLength(uint pathId); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_evaluate")] + public static partial void PathEvaluate(Vector2* pOut, uint pathId, float t); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_tangent")] + public static partial void PathTangent(Vector2* pOut, uint pathId, float t); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_angle")] + public static partial float PathAngle(uint pathId, float t); + + // Tween along a path + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_path")] + public static partial void TweenPath(Vector2* pOut, uint id, uint channelId, uint pathId, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt = -1f); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_path_angle")] + public static partial float TweenPathAngle(uint id, uint channelId, uint pathId, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, float dt = -1f); + + + // ---------------------------------------------------- + // Arc-length parameterization (for constant-speed animation) + // ---------------------------------------------------- + + // Build arc-length lookup table for a path (call once per path, improves accuracy) + + [LibraryImport(LibName, EntryPoint = "c_iam_path_build_arc_lut")] + public static partial void PathBuildArcLut(uint pathId, int subdivisions); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_has_arc_lut")] + public static partial byte PathHasArcLut(uint pathId); + + // Distance-based path evaluation (uses arc-length LUT for constant speed) + + [LibraryImport(LibName, EntryPoint = "c_iam_path_distance_to_t")] + public static partial float PathDistanceToT(uint pathId, float distance); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_evaluate_at_distance")] + public static partial void PathEvaluateAtDistance(Vector2* pOut, uint pathId, float distance); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_angle_at_distance")] + public static partial float PathAngleAtDistance(uint pathId, float distance); + + [LibraryImport(LibName, EntryPoint = "c_iam_path_tangent_at_distance")] + public static partial void PathTangentAtDistance(Vector2* pOut, uint pathId, float distance); + + + // ---------------------------------------------------- + // Path Morphing - interpolate between two paths + // ---------------------------------------------------- + + // Evaluate morphed path at parameter t [0,1] with blend factor [0,1] + // path_a at blend=0, path_b at blend=1 + // Paths can have different numbers of segments - they are resampled to match + [LibraryImport(LibName, EntryPoint = "c_iam_path_morph")] + public static partial void PathMorph(Vector2* pOut, uint pathA, uint pathB, float t, float blend, ImAnimMorphOpts* opts = null); + + // Get tangent of morphed path + [LibraryImport(LibName, EntryPoint = "c_iam_path_morph_tangent")] + public static partial void PathMorphTangent(Vector2* pOut, uint pathA, uint pathB, float t, float blend, ImAnimMorphOpts* opts = null); + + // Get angle (radians) of morphed path + [LibraryImport(LibName, EntryPoint = "c_iam_path_morph_angle")] + public static partial float PathMorphAngle(uint pathA, uint pathB, float t, float blend, ImAnimMorphOpts* opts = null); + + // Tween along a morphing path - animates both position along path AND the morph blend + [LibraryImport(LibName, EntryPoint = "c_iam_tween_path_morph")] + public static partial void TweenPathMorph(Vector2* pOut, uint id, uint channelId, uint pathA, uint pathB, float targetBlend, float dur, ImAnimEaseDesc* pathEase, ImAnimEaseDesc* morphEase, ImAnimPolicy policy, float dt, ImAnimMorphOpts* opts = null); + + // Get current morph blend value from a tween (for querying state) + [LibraryImport(LibName, EntryPoint = "c_iam_get_morph_blend")] + public static partial float GetMorphBlend(uint id, uint channelId); + + + // ---------------------------------------------------- + // Text along motion paths + // ---------------------------------------------------- + + // Render text along a path (static - no animation) + [LibraryImport(LibName, EntryPoint = "c_iam_text_path")] + public static partial void TextPath(uint pathId, byte* text, ImAnimTextPathOpts* opts = null); + + // Animated text along path (characters appear progressively) + [LibraryImport(LibName, EntryPoint = "c_iam_text_path_animated")] + public static partial void TextPathAnimated(uint pathId, byte* text, float progress, ImAnimTextPathOpts* opts = null); + + // Helper: Get text width for path layout calculations + [LibraryImport(LibName, EntryPoint = "c_iam_text_path_width")] + public static partial float TextPathWidth(byte* text, ImAnimTextPathOpts* opts = null); + + + // ---------------------------------------------------- + // Quad transform helpers (for advanced custom rendering) + // ---------------------------------------------------- + + // Transform a quad (4 vertices) by rotation and translation + [LibraryImport(LibName, EntryPoint = "c_iam_transform_quad")] + public static partial void TransformQuad(Quaternion* quad, Vector2* center, float angleRad, Vector2* translation); + + // Create a rotated quad for a glyph at a position on the path + [LibraryImport(LibName, EntryPoint = "c_iam_make_glyph_quad")] + public static partial void MakeGlyphQuad(Quaternion* quad, Vector2* pos, float angleRad, float glyphWidth, float glyphHeight, float baselineOffset); + + + // ---------------------------------------------------- + // Text Stagger - per-character animation effects + // ---------------------------------------------------- + + // Render text with per-character stagger animation + [LibraryImport(LibName, EntryPoint = "c_iam_text_stagger")] + public static partial void TextStagger(uint id, byte* text, float progress, ImAnimTextStaggerOpts* opts = null); + + // Get text width for layout calculations + [LibraryImport(LibName, EntryPoint = "c_iam_text_stagger_width")] + public static partial float TextStaggerWidth(byte* text, ImAnimTextStaggerOpts* opts = null); + + // Get total animation duration for text (accounts for stagger delays) + [LibraryImport(LibName, EntryPoint = "c_iam_text_stagger_duration")] + public static partial float TextStaggerDuration(byte* text, ImAnimTextStaggerOpts* opts = null); + + + // ---------------------------------------------------- + // Noise Channels - Perlin/Simplex noise for organic movement + // ---------------------------------------------------- + + // Sample noise at a point (returns value in [-1, 1]) + + [LibraryImport(LibName, EntryPoint = "c_iam_noise_2d")] + public static partial float Noise2D(float x, float y, ImAnimNoiseOpts* opts = null); + + [LibraryImport(LibName, EntryPoint = "c_iam_noise_3d")] + public static partial float Noise3D(float x, float y, float z, ImAnimNoiseOpts* opts = null); + + // Animated noise channels - continuous noise that evolves over time + + [LibraryImport(LibName, EntryPoint = "c_iam_noise_channel_float")] + public static partial float NoiseChannelFloat(uint id, float frequency, float amplitude, ImAnimNoiseOpts* opts, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_noise_channel_vec2")] + public static partial void NoiseChannelVec2(Vector2* pOut, uint id, Vector2* frequency, Vector2* amplitude, ImAnimNoiseOpts* opts, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_noise_channel_vec4")] + public static partial void NoiseChannelVec4(Vector4* pOut, uint id, Vector4* frequency, Vector4* amplitude, ImAnimNoiseOpts* opts, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_noise_channel_color")] + public static partial void NoiseChannelColor(Vector4* pOut, uint id, Vector4* baseColor, Vector4* amplitude, float frequency, ImAnimNoiseOpts* opts, ImAnimColorSpace colorSpace, float dt); + + // Convenience: smooth random movement (like wiggle but using noise) + + [LibraryImport(LibName, EntryPoint = "c_iam_smooth_noise_float")] + public static partial float SmoothNoiseFloat(uint id, float amplitude, float speed, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_smooth_noise_vec2")] + public static partial void SmoothNoiseVec2(Vector2* pOut, uint id, Vector2* amplitude, float speed, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_smooth_noise_vec4")] + public static partial void SmoothNoiseVec4(Vector4* pOut, uint id, Vector4* amplitude, float speed, float dt); + + [LibraryImport(LibName, EntryPoint = "c_iam_smooth_noise_color")] + public static partial void SmoothNoiseColor(Vector4* pOut, uint id, Vector4* baseColor, Vector4* amplitude, float speed, ImAnimColorSpace colorSpace, float dt); + + + // ---------------------------------------------------- + // Style Interpolation - animate between ImGuiStyle themes + // ---------------------------------------------------- + + // Register a named style for interpolation + [LibraryImport(LibName, EntryPoint = "c_iam_style_register")] + public static partial void StyleRegister(uint styleId, ImGuiStyle* style); + + [LibraryImport(LibName, EntryPoint = "c_iam_style_register_current")] + public static partial void StyleRegisterCurrent(uint styleId); + + // Blend between two registered styles (result applied to ImGui::GetStyle()) + // Uses iam_color_space for color blending mode (iam_col_oklab recommended) + [LibraryImport(LibName, EntryPoint = "c_iam_style_blend")] + public static partial void StyleBlend(uint styleA, uint styleB, float t, ImAnimColorSpace colorSpace = ImAnimColorSpace.Oklab); + + // Tween between styles over time + [LibraryImport(LibName, EntryPoint = "c_iam_style_tween")] + public static partial void StyleTween(uint id, uint targetStyle, float duration, ImAnimEaseDesc* ease, ImAnimColorSpace colorSpace, float dt); + + // Get interpolated style without applying + [LibraryImport(LibName, EntryPoint = "c_iam_style_blend_to")] + public static partial void StyleBlendTo(uint styleA, uint styleB, float t, ImGuiStyle* outStyle, ImAnimColorSpace colorSpace = ImAnimColorSpace.Oklab); + + // Check if a style is registered + [LibraryImport(LibName, EntryPoint = "c_iam_style_exists")] + public static partial byte StyleExists(uint styleId); + + // Remove a registered style + [LibraryImport(LibName, EntryPoint = "c_iam_style_unregister")] + public static partial void StyleUnregister(uint styleId); + + + // ---------------------------------------------------- + // Gradient Interpolation - animate between color gradients + // ---------------------------------------------------- + + // Blend between two gradients + [LibraryImport(LibName, EntryPoint = "c_iam_gradient_lerp")] + public static partial void GradientLerp(ImAnimGradient* pOut, ImAnimGradient* a, ImAnimGradient* b, float t, ImAnimColorSpace colorSpace = ImAnimColorSpace.Oklab); + + [LibraryImport(LibName, EntryPoint = "c_iam_tween_gradient")] + public static partial void TweenGradient(ImAnimGradient* pOut, uint id, uint channelId, ImAnimGradient* target, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, ImAnimColorSpace colorSpace, float dt); + + + // ---------------------------------------------------- + // Transform Interpolation - animate 2D transforms + // ---------------------------------------------------- + + // Blend between two transforms with rotation interpolation + [LibraryImport(LibName, EntryPoint = "c_iam_transform_lerp")] + public static partial void TransformLerp(ImAnimTransform* pOut, ImAnimTransform* a, ImAnimTransform* b, float t, ImAnimRotationMode rotationMode = ImAnimRotationMode.Shortest); + + // Tween between transforms over time + [LibraryImport(LibName, EntryPoint = "c_iam_tween_transform")] + public static partial void TweenTransform(ImAnimTransform* pOut, uint id, uint channelId, ImAnimTransform* target, float dur, ImAnimEaseDesc* ez, ImAnimPolicy policy, int rotationMode, float dt); + + // Decompose a 3x2 matrix into transform components + [LibraryImport(LibName, EntryPoint = "c_iam_transform_from_matrix")] + public static partial void TransformFromMatrix(ImAnimTransform* pOut, float m00, float m01, float m10, float m11, float tx, float ty); + + // Convert transform to 3x2 matrix (row-major: [m00 m01 tx; m10 m11 ty]) + [LibraryImport(LibName, EntryPoint = "c_iam_transform_to_matrix")] + public static partial void TransformToMatrix(ImAnimTransform* t, Matrix3x2* outMatrix); + + + // ---------------------------------------------------- + // iam_clip - fluent API for authoring animations + // ---------------------------------------------------- + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_begin")] + public static partial void ClipBegin(ImAnimClip* pOut, uint clipId); + + // Add keyframes for different channel types + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_float")] + public static partial void ClipKeyFloat(ImAnimClip* self, uint channel, float time, float value, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_vec2")] + public static partial void ClipKeyVec2(ImAnimClip* self, uint channel, float time, Vector2* value, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_vec4")] + public static partial void ClipKeyVec4(ImAnimClip* self, uint channel, float time, Vector4* value, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_int")] + public static partial void ClipKeyInt(ImAnimClip* self, uint channel, float time, int value, ImAnimEaseType easeType); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_color")] + public static partial void ClipKeyColor(ImAnimClip* self, uint channel, float time, Vector4* value, ImAnimColorSpace colorSpace, ImAnimEaseType easeType, Vector4* bezier4); + + // Keyframes with repeat variation (value changes per loop iteration) + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_float_var")] + public static partial void ClipKeyFloatVar(ImAnimClip* self, uint channel, float time, float value, ImAnimVariationFloat* var, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_vec2_var")] + public static partial void ClipKeyVec2Var(ImAnimClip* self, uint channel, float time, Vector2* value, ImAnimVariationVec2* var, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_vec4_var")] + public static partial void ClipKeyVec4Var(ImAnimClip* self, uint channel, float time, Vector4* value, ImAnimVariationVec4* var, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_int_var")] + public static partial void ClipKeyIntVar(ImAnimClip* self, uint channel, float time, int value, ImAnimVariationInt* var, ImAnimEaseType easeType); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_color_var")] + public static partial void ClipKeyColorVar(ImAnimClip* self, uint channel, float time, Vector4* value, ImAnimVariationColor* var, ImAnimColorSpace colorSpace, ImAnimEaseType easeType, Vector4* bezier4); + + // Spring-based keyframe (float only) + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_float_spring")] + public static partial void ClipKeyFloatSpring(ImAnimClip* self, uint channel, float time, float target, ImAnimSpringParams* spring); + + // Anchor-relative keyframes (values resolved relative to window/viewport at get time) + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_float_rel")] + public static partial void ClipKeyFloatRel(ImAnimClip* self, uint channel, float time, float percent, float pxBias, ImAnimAnchorSpace anchorSpace, int axis, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_vec2_rel")] + public static partial void ClipKeyVec2Rel(ImAnimClip* self, uint channel, float time, Vector2* percent, Vector2* pxBias, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_vec4_rel")] + public static partial void ClipKeyVec4Rel(ImAnimClip* self, uint channel, float time, Vector4* percent, Vector4* pxBias, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType, Vector4* bezier4); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_key_color_rel")] + public static partial void ClipKeyColorRel(ImAnimClip* self, uint channel, float time, Vector4* percent, Vector4* pxBias, ImAnimColorSpace colorSpace, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType, Vector4* bezier4); + + // Timeline grouping - sequential and parallel keyframe blocks + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_seq_begin")] + public static partial void ClipSeqBegin(ImAnimClip* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_seq_end")] + public static partial void ClipSeqEnd(ImAnimClip* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_par_begin")] + public static partial void ClipParBegin(ImAnimClip* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_par_end")] + public static partial void ClipParEnd(ImAnimClip* self); + + // Timeline markers - callbacks at specific times during playback + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_marker_id")] + public static partial void ClipMarkerId(ImAnimClip* self, float time, uint markerId, delegate* unmanaged[Cdecl] cb, void* userData); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_marker")] + public static partial void ClipMarker(ImAnimClip* self, float time, delegate* unmanaged[Cdecl] cb, void* userData); + + // Clip options + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_set_loop")] + public static partial void ClipSetLoop(ImAnimClip* self, byte loop, ImAnimDirection direction, int loopCount); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_set_delay")] + public static partial void ClipSetDelay(ImAnimClip* self, float delaySeconds); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_set_stagger")] + public static partial void ClipSetStagger(ImAnimClip* self, int count, float eachDelay, float fromCenterBias); + + // Timing variation per loop iteration + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_set_duration_var")] + public static partial void ClipSetDurationVar(ImAnimClip* self, ImAnimVariationFloat* var); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_set_delay_var")] + public static partial void ClipSetDelayVar(ImAnimClip* self, ImAnimVariationFloat* var); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_set_timescale_var")] + public static partial void ClipSetTimescaleVar(ImAnimClip* self, ImAnimVariationFloat* var); + + // Callbacks + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_on_begin")] + public static partial void ClipOnBegin(ImAnimClip* self, delegate* unmanaged[Cdecl] cb, void* userData); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_on_update")] + public static partial void ClipOnUpdate(ImAnimClip* self, delegate* unmanaged[Cdecl] cb, void* userData); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_on_complete")] + public static partial void ClipOnComplete(ImAnimClip* self, delegate* unmanaged[Cdecl] cb, void* userData); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_end")] + public static partial void ClipEnd(ImAnimClip* self); + + + // ---------------------------------------------------- + // iam_instance - playback control for a clip + // ---------------------------------------------------- + + // Playback control + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_pause")] + public static partial void InstancePause(ImAnimInstance* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_resume")] + public static partial void InstanceResume(ImAnimInstance* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_stop")] + public static partial void InstanceStop(ImAnimInstance* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_destroy_playback")] + public static partial void InstanceDestroyPlayback(ImAnimInstance* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_seek")] + public static partial void InstanceSeek(ImAnimInstance* self, float time); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_set_time_scale")] + public static partial void InstanceSetTimeScale(ImAnimInstance* self, float scale); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_set_weight")] + public static partial void InstanceSetWeight(ImAnimInstance* self, float weight); + + // Animation chaining - play another clip when this one completes + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_then")] + public static partial void InstanceThen(ImAnimInstance* pOut, ImAnimInstance* self, uint nextClipId); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_then_id")] + public static partial void InstanceThenId(ImAnimInstance* pOut, ImAnimInstance* self, uint nextClipId, uint nextInstanceId); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_then_delay")] + public static partial void InstanceThenDelay(ImAnimInstance* pOut, ImAnimInstance* self, float delay); + + // Query state + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_time")] + public static partial float InstanceTime(ImAnimInstance* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_duration")] + public static partial float InstanceDuration(ImAnimInstance* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_is_playing")] + public static partial byte InstanceIsPlaying(ImAnimInstance* self); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_is_paused")] + public static partial byte InstanceIsPaused(ImAnimInstance* self); + + // Get animated values + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_get_float")] + public static partial byte InstanceGetFloat(ImAnimInstance* self, uint channel, float* outVal); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_get_vec2")] + public static partial byte InstanceGetVec2(ImAnimInstance* self, uint channel, Vector2* outVal); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_get_vec4")] + public static partial byte InstanceGetVec4(ImAnimInstance* self, uint channel, Vector4* outVal); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_get_int")] + public static partial byte InstanceGetInt(ImAnimInstance* self, uint channel, int* outVal); + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_get_color")] + public static partial byte InstanceGetColor(ImAnimInstance* self, uint channel, Vector4* outVal, ImAnimColorSpace colorSpace); + + // Check validity + + [LibraryImport(LibName, EntryPoint = "c_iam_instance_valid")] + public static partial byte InstanceValid(ImAnimInstance* self); + + + // ---------------------------------------------------- + // Clip System API + // ---------------------------------------------------- + + // Initialize/shutdown (optional - auto-init on first use) + [LibraryImport(LibName, EntryPoint = "c_iam_clip_init")] + public static partial void ClipInit(int initialClipCap, int initialInstCap); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_shutdown")] + public static partial void ClipShutdown(); + + // c_Per-frame update (call after iam_update_begin_frame) + [LibraryImport(LibName, EntryPoint = "c_iam_clip_update")] + public static partial void ClipUpdate(float dt); + + // Garbage collection for instances + [LibraryImport(LibName, EntryPoint = "c_iam_clip_gc")] + public static partial void ClipGc(uint maxAgeFrames); + + // Play a clip on an instance (creates or reuses instance) + [LibraryImport(LibName, EntryPoint = "c_iam_play")] + public static partial void Play(ImAnimInstance* pOut, uint clipId, uint instanceId); + + // c_Get an existing instance (returns invalid iam_instance if not found) + [LibraryImport(LibName, EntryPoint = "c_iam_get_instance")] + public static partial void GetInstance(ImAnimInstance* pOut, uint instanceId); + + // Query clip info + [LibraryImport(LibName, EntryPoint = "c_iam_clip_duration")] + public static partial float ClipDuration(uint clipId); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_exists")] + public static partial byte ClipExists(uint clipId); + + // Stagger helpers - compute delay for indexed instances + [LibraryImport(LibName, EntryPoint = "c_iam_stagger_delay")] + public static partial float StaggerDelay(uint clipId, int index); + + [LibraryImport(LibName, EntryPoint = "c_iam_play_stagger")] + public static partial void PlayStagger(ImAnimInstance* pOut, uint clipId, uint instanceId, int index); + + // Layering support - blend multiple animation instances + [LibraryImport(LibName, EntryPoint = "c_iam_layer_begin")] + public static partial void LayerBegin(uint instanceId); + + [LibraryImport(LibName, EntryPoint = "c_iam_layer_add")] + public static partial void LayerAdd(ImAnimInstance* inst, float weight); + + [LibraryImport(LibName, EntryPoint = "c_iam_layer_end")] + public static partial void LayerEnd(uint instanceId); + + [LibraryImport(LibName, EntryPoint = "c_iam_get_blended_float")] + public static partial byte GetBlendedFloat(uint instanceId, uint channel, float* outVal); + + [LibraryImport(LibName, EntryPoint = "c_iam_get_blended_vec2")] + public static partial byte GetBlendedVec2(uint instanceId, uint channel, Vector2* outVal); + + [LibraryImport(LibName, EntryPoint = "c_iam_get_blended_vec4")] + public static partial byte GetBlendedVec4(uint instanceId, uint channel, Vector4* outVal); + + [LibraryImport(LibName, EntryPoint = "c_iam_get_blended_int")] + public static partial byte GetBlendedInt(uint instanceId, uint channel, int* outVal); + + // Persistence (optional) + [LibraryImport(LibName, EntryPoint = "c_iam_clip_save")] + public static partial ImAnimResult ClipSave(uint clipId, byte* path); + + [LibraryImport(LibName, EntryPoint = "c_iam_clip_load")] + public static partial ImAnimResult ClipLoad(byte* path, uint* outClipId); +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimClip.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimClip.cs new file mode 100644 index 000000000..816904c73 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimClip.cs @@ -0,0 +1,338 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +using Dalamud.Bindings.ImGui; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimClip +{ + public uint ClipId; + + public static ImAnimClip Begin(uint clipId) + { + return ImAnim.ClipBegin(clipId); + } + + public ImAnimClip KeyFloat(uint channel, float time, float value, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyFloat(@this, channel, time, value, easeType, null); + return this; + } + + public ImAnimClip KeyFloat(uint channel, float time, float value, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyFloat(@this, channel, time, value, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyVec2(uint channel, float time, Vector2 value, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec2(@this, channel, time, &value, easeType, null); + return this; + } + + public ImAnimClip KeyVec2(uint channel, float time, Vector2 value, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec2(@this, channel, time, &value, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyVec4(uint channel, float time, Vector4 value, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec4(@this, channel, time, &value, easeType, null); + return this; + } + + public ImAnimClip KeyVec4(uint channel, float time, Vector4 value, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec4(@this, channel, time, &value, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyInt(uint channel, float time, int value, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyInt(@this, channel, time, value, easeType); + return this; + } + + public ImAnimClip KeyColor(uint channel, float time, Vector4 value, ImAnimColorSpace colorSpace, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyColor(@this, channel, time, &value, colorSpace, easeType, null); + return this; + } + + public ImAnimClip KeyColor(uint channel, float time, Vector4 value, ImAnimColorSpace colorSpace, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyColor(@this, channel, time, &value, colorSpace, easeType, &bezier4); + return this; + } + + // Keyframes with repeat variation (value changes per loop iteration) + + public ImAnimClip KeyFloatVar(uint channel, float time, float value, ImAnimVariationFloat var, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyFloatVar(@this, channel, time, value, &var, easeType, null); + return this; + } + + public ImAnimClip KeyFloatVar(uint channel, float time, float value, ImAnimVariationFloat var, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyFloatVar(@this, channel, time, value, &var, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyVec2Var(uint channel, float time, Vector2 value, ImAnimVariationVec2 var, ImAnimEaseType easeType) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec2Var(@this, channel, time, &value, &var, easeType, null); + return this; + } + + public ImAnimClip KeyVec2Var(uint channel, float time, Vector2 value, ImAnimVariationVec2 var, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec2Var(@this, channel, time, &value, &var, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyVec4Var(uint channel, float time, Vector4 value, ImAnimVariationVec4 var, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec4Var(@this, channel, time, &value, &var, easeType, null); + return this; + } + + public ImAnimClip KeyVec4Var(uint channel, float time, Vector4 value, ImAnimVariationVec4 var, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec4Var(@this, channel, time, &value, &var, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyIntVar(uint channel, float time, int value, ImAnimVariationInt var, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyIntVar(@this, channel, time, value, &var, easeType); + return this; + } + + public ImAnimClip KeyColorVar(uint channel, float time, Vector4 value, ImAnimVariationColor var, ImAnimColorSpace colorSpace, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyColorVar(@this, channel, time, &value, &var, colorSpace, easeType, null); + return this; + } + + public ImAnimClip KeyColorVar(uint channel, float time, Vector4 value, ImAnimVariationColor var, ImAnimColorSpace colorSpace, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyColorVar(@this, channel, time, &value, &var, colorSpace, easeType, &bezier4); + return this; + } + + // Spring-based keyframe (float only) + + public ImAnimClip KeyFloatSpring(uint channel, float time, float target, ImAnimSpringParams spring) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyFloatSpring(@this, channel, time, target, &spring); + return this; + } + + // Anchor-relative keyframes (values resolved relative to window/viewport at get time) + + public ImAnimClip KeyFloatRel(uint channel, float time, float percent, float pxBias, ImAnimAnchorSpace anchorSpace, int axis, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyFloatRel(@this, channel, time, percent, pxBias, anchorSpace, axis, easeType, null); + return this; + } + + public ImAnimClip KeyFloatRel(uint channel, float time, float percent, float pxBias, ImAnimAnchorSpace anchorSpace, int axis, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyFloatRel(@this, channel, time, percent, pxBias, anchorSpace, axis, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyVec2Rel(uint channel, float time, Vector2 percent, Vector2 pxBias, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec2Rel(@this, channel, time, &percent, &pxBias, anchorSpace, easeType, null); + return this; + } + + public ImAnimClip KeyVec2Rel(uint channel, float time, Vector2 percent, Vector2 pxBias, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec2Rel(@this, channel, time, &percent, &pxBias, anchorSpace, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyVec4Rel(uint channel, float time, Vector4 percent, Vector4 pxBias, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec4Rel(@this, channel, time, &percent, &pxBias, anchorSpace, easeType, null); + return this; + } + + public ImAnimClip KeyVec4Rel(uint channel, float time, Vector4 percent, Vector4 pxBias, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyVec4Rel(@this, channel, time, &percent, &pxBias, anchorSpace, easeType, &bezier4); + return this; + } + + public ImAnimClip KeyColorRel(uint channel, float time, Vector4 percent, Vector4 pxBias, ImAnimColorSpace colorSpace, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType = ImAnimEaseType.Linear) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyColorRel(@this, channel, time, &percent, &pxBias, colorSpace, anchorSpace, easeType, null); + return this; + } + + public ImAnimClip KeyColorRel(uint channel, float time, Vector4 percent, Vector4 pxBias, ImAnimColorSpace colorSpace, ImAnimAnchorSpace anchorSpace, ImAnimEaseType easeType, Vector4 bezier4) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipKeyColorRel(@this, channel, time, &percent, &pxBias, colorSpace, anchorSpace, easeType, &bezier4); + return this; + } + + // Timeline grouping - sequential and parallel keyframe blocks + + public ImAnimClip SeqBegin() + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSeqBegin(@this); + return this; + } + + public ImAnimClip SeqEnd() + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSeqEnd(@this); + return this; + } + + public ImAnimClip ParBegin() + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipParBegin(@this); + return this; + } + + public ImAnimClip ParEnd() + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipParEnd(@this); + return this; + } + + // Timeline markers - callbacks at specific times during playback + + public ImAnimClip MarkerId(float time, uint markerId, ImAnim.MarkerCallback cb, void* userData = null) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipMarkerId(@this, time, markerId, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(cb), userData); + return this; + } + + public ImAnimClip Marker(float time, ImAnim.MarkerCallback cb, void* userData = null) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipMarker(@this, time, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(cb), userData); + return this; + } + + // Clip options + + public ImAnimClip SetLoop(bool loop, ImAnimDirection direction, int loopCount = -1) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSetLoop(@this, (byte)(loop ? 1 : 0), direction, loopCount); + return this; + } + + public ImAnimClip SetDelay(float delaySeconds) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSetDelay(@this, delaySeconds); + return this; + } + + public ImAnimClip SetStagger(int count, float eachDelay, float fromCenterBias) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSetStagger(@this, count, eachDelay, fromCenterBias); + return this; + } + + // Timing variation per loop iteration + + public ImAnimClip SetDurationVar(ImAnimVariationFloat var) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSetDurationVar(@this, &var); + return this; + } + + public ImAnimClip SetDelayVar(ImAnimVariationFloat var) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSetDelayVar(@this, &var); + return this; + } + + public ImAnimClip SetTimescaleVar(ImAnimVariationFloat var) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipSetTimescaleVar(@this, &var); + return this; + } + + // Callbacks + + public ImAnimClip OnBegin(ImAnim.ClipCallback cb, void* userData = null) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipOnBegin(@this, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(cb), userData); + return this; + } + + public ImAnimClip OnUpdate(ImAnim.ClipCallback cb, void* userData = null) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipOnUpdate(@this, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(cb), userData); + return this; + } + + public ImAnimClip OnComplete(ImAnim.ClipCallback cb, void* userData = null) + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipOnComplete(@this, (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(cb), userData); + return this; + } + + public void End() + { + fixed (ImAnimClip* @this = &this) + ImAnimNative.ClipEnd(@this); + } + + public ImAnimResult Save(ImU8String path) + { + return ImAnim.ClipSave(this.ClipId, path); + } +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragFeedback.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragFeedback.cs new file mode 100644 index 000000000..0ce7a9c0a --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragFeedback.cs @@ -0,0 +1,15 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public struct ImAnimDragFeedback +{ + public Vector2 Position; + public Vector2 Offset; + public Vector2 Velocity; + public bool IsDragging; + public bool IsSnapping; + public float SnapProgress; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragOpts.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragOpts.cs new file mode 100644 index 000000000..ee599fe45 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimDragOpts.cs @@ -0,0 +1,17 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimDragOpts +{ + public Vector2 SnapGrid; + public Vector2* SnapPoints; + public int SnapPointsCount; + public float SnapDuration; + public float Overshoot; + public ImAnimEaseType EaseType; + + public static ImAnimDragOpts Default() => new() { SnapDuration = 0.2f, EaseType = ImAnimEaseType.OutCubic }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEaseDesc.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEaseDesc.cs new file mode 100644 index 000000000..fd6adbd8a --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEaseDesc.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public struct ImAnimEaseDesc +{ + public ImAnimEaseType Type; + public float P0; + public float P1; + public float P2; + public float P3; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEasePerAxis.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEasePerAxis.cs new file mode 100644 index 000000000..df0d28caa --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimEasePerAxis.cs @@ -0,0 +1,28 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public struct ImAnimEasePerAxis +{ + public ImAnimEaseDesc X; + public ImAnimEaseDesc Y; + public ImAnimEaseDesc Z; + public ImAnimEaseDesc W; + + public static ImAnimEasePerAxis From(ImAnimEaseDesc all) => new() + { + X = all, + Y = all, + Z = all, + W = all + }; + + public static ImAnimEasePerAxis From(ImAnimEaseDesc ex, ImAnimEaseDesc ey) => new() + { + X = ex, + Y = ey, + Z = new ImAnimEaseDesc { Type = ImAnimEaseType.Linear }, + W = new ImAnimEaseDesc { Type = ImAnimEaseType.Linear } + }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimGradient.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimGradient.cs new file mode 100644 index 000000000..1b00fab60 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimGradient.cs @@ -0,0 +1,13 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +using Dalamud.Bindings.ImGui; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimGradient +{ + public ImVector Positions; + public ImVector Colors; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimInstance.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimInstance.cs new file mode 100644 index 000000000..8d1b5721e --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimInstance.cs @@ -0,0 +1,155 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimInstance +{ + public uint InstId; + + // Playback control + + public static ImAnimInstance Create() + { + return new ImAnimInstance(); + } + + public static ImAnimInstance Create(uint instId) + { + return new ImAnimInstance() { InstId = instId }; + } + + public void Pause() + { + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstancePause(@this); + } + + public void Resume() + { + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceResume(@this); + } + + public void Stop() + { + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceStop(@this); + } + + public void Seek(float time) + { + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceSeek(@this, time); + } + + public void SetTimeScale(float scale) + { + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceSetTimeScale(@this, scale); + } + + public void SetWeight(float weight) + { + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceSetWeight(@this, weight); + } + + // Animation chaining - play another clip when this one completes + + public ImAnimInstance Then(uint nextClipId) + { + ImAnimInstance ret = default; + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceThen(&ret, @this, nextClipId); + return ret; + } + + public ImAnimInstance Then(uint nextClipId, uint nextInstanceId) + { + ImAnimInstance ret = default; + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceThenId(&ret, @this, nextClipId, nextInstanceId); + return ret; + } + + public ImAnimInstance ThenDelay(float delay) + { + ImAnimInstance ret = default; + fixed (ImAnimInstance* @this = &this) + ImAnimNative.InstanceThenDelay(&ret, @this, delay); + return ret; + } + + // Query state + + public float Time() + { + fixed (ImAnimInstance* @this = &this) + return ImAnimNative.InstanceTime(@this); + } + + public float Duration() + { + fixed (ImAnimInstance* @this = &this) + return ImAnimNative.InstanceDuration(@this); + } + + public bool IsPlaying() + { + fixed (ImAnimInstance* @this = &this) + return ImAnimNative.InstanceIsPlaying(@this) == 1; + } + + public bool IsPaused() + { + fixed (ImAnimInstance* @this = &this) + return ImAnimNative.InstanceIsPaused(@this) == 1; + } + + // Get animated values + + public bool GetFloat(uint channel, out float value) + { + fixed (ImAnimInstance* @this = &this) + fixed (float* outVal = &value) + return ImAnimNative.InstanceGetFloat(@this, channel, outVal) == 1; + } + + public bool GetVec2(uint channel, out Vector2 value) + { + fixed (ImAnimInstance* @this = &this) + fixed (Vector2* outVal = &value) + return ImAnimNative.InstanceGetVec2(@this, channel, outVal) == 1; + } + + public bool GetVec4(uint channel, out Vector4 value) + { + fixed (ImAnimInstance* @this = &this) + fixed (Vector4* outVal = &value) + return ImAnimNative.InstanceGetVec4(@this, channel, outVal) == 1; + } + + public bool GetInt(uint channel, out int value) + { + fixed (ImAnimInstance* @this = &this) + fixed (int* outVal = &value) + return ImAnimNative.InstanceGetInt(@this, channel, outVal) == 1; + } + + public bool GetColor(uint channel, out Vector4 value, ImAnimColorSpace colorSpace = ImAnimColorSpace.Oklab) + { + fixed (ImAnimInstance* @this = &this) + fixed (Vector4* outVal = &value) + return ImAnimNative.InstanceGetColor(@this, channel, outVal, colorSpace) == 1; + } + + // Check validity + + public bool Valid() + { + fixed (ImAnimInstance* @this = &this) + return ImAnimNative.InstanceValid(@this) == 1; + } +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimMorphOpts.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimMorphOpts.cs new file mode 100644 index 000000000..edead66f5 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimMorphOpts.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public struct ImAnimMorphOpts +{ + public int Samples; + public bool MatchEndpoints; + public bool UseArcLength; + + public static ImAnimMorphOpts Default() => new() { Samples = 64, MatchEndpoints = true, UseArcLength = true }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimNoiseOpts.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimNoiseOpts.cs new file mode 100644 index 000000000..e2fea1f4f --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimNoiseOpts.cs @@ -0,0 +1,28 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimNoiseOpts +{ + public ImAnimNoiseType Type; + /// + /// Number of octaves for fractal noise (1-8) + /// + public int Octaves; + + /// + /// Amplitude multiplier per octave (0.0-1.0) + /// + public float Persistence; + + /// + /// Frequency multiplier per octave (typically 2.0) + /// + public float Lacunarity; + + /// + /// Random seed for noise generation + /// + public int Seed; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimSpringParams.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimSpringParams.cs new file mode 100644 index 000000000..48fbff60d --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimSpringParams.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential, Pack = 4)] +public struct ImAnimSpringParams +{ + public float Mass; + public float Stiffness; + public float Damping; + public float InitialVelocity; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextPathOpts.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextPathOpts.cs new file mode 100644 index 000000000..e9908291c --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextPathOpts.cs @@ -0,0 +1,21 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +using Dalamud.Bindings.ImGui; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public struct ImAnimTextPathOpts +{ + public Vector2 Origin; + public float Offset; + public float LetterSpacing; + public ImAnimTextPathAlign Align; + public bool FlipY; + public uint Color; + public ImFontPtr Font; + public float FontScale; + + public static ImAnimTextPathOpts Default() => new() { Color = 0xFFFFFFFF, FontScale = 1.0f }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextStaggerOpts.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextStaggerOpts.cs new file mode 100644 index 000000000..bab6d54dc --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTextStaggerOpts.cs @@ -0,0 +1,32 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +using Dalamud.Bindings.ImGui; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimTextStaggerOpts +{ + public Vector2 Pos; + public ImAnimTextStaggerEffect Effect; + public float CharDelay; + public float CharDuration; + public float EffectIntensity; + public ImAnimEaseDesc Ease; + public uint Color; + public ImFontPtr Font; + public float FontScale; + public float LetterSpacing; + + public static ImAnimTextStaggerOpts Default() => new() + { + Effect = ImAnimTextStaggerEffect.Fade, + CharDelay = 0.05f, + CharDuration = 0.3f, + EffectIntensity = 20.0f, + Ease = new ImAnimEaseDesc { Type = ImAnimEaseType.OutCubic }, + Color = 0xFFFFFFFF, + FontScale = 1.0f + }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTransform.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTransform.cs new file mode 100644 index 000000000..339066a91 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimTransform.cs @@ -0,0 +1,12 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimTransform +{ + public Vector2 Position; + public Vector2 Scale; + public float Rotation; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationColor.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationColor.cs new file mode 100644 index 000000000..2d48006ea --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationColor.cs @@ -0,0 +1,170 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimVariationColor +{ + public ImAnimVariationMode Mode; + public Vector4 Amount; + public Vector4 MinClamp; + public Vector4 MaxClamp; + public ImAnimColorSpace ColorSpace; + public delegate* unmanaged[Cdecl] Callback; + public void* User; + public ImAnimVariationFloat R; + public ImAnimVariationFloat G; + public ImAnimVariationFloat B; + public ImAnimVariationFloat A; + + public static ImAnimVariationColor None => new() + { + Mode = ImAnimVariationMode.None, + Amount = Vector4.Zero, + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Inc(Vector4 color) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = color, + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Inc(float r, float g, float b, float a) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = new Vector4(r, g, b, a), + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Dec(Vector4 color) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = color, + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Dec(float r, float g, float b, float a) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = new Vector4(r, g, b, a), + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Mul(float f) => new() + { + Mode = ImAnimVariationMode.Multiply, + Amount = new Vector4(f, f, f, 1), + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Rand(Vector4 acolort) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = acolort, + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Rand(float r, float g, float b, float a) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = new Vector4(r, g, b, a), + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Fn(ImAnim.VariationVec4Fn fn, void* userData = null) => new() + { + Mode = ImAnimVariationMode.Callback, + Amount = Vector4.Zero, + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), + User = userData, + R = ImAnimVariationFloat.None, + G = ImAnimVariationFloat.None, + B = ImAnimVariationFloat.None, + A = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationColor Axis(ImAnimVariationFloat vr, ImAnimVariationFloat vg, ImAnimVariationFloat vb, ImAnimVariationFloat va) => new() + { + Mode = ImAnimVariationMode.None, + Amount = Vector4.Zero, + MinClamp = Vector4.Zero, + MaxClamp = Vector4.One, + ColorSpace = ImAnimColorSpace.Oklab, + Callback = null, + User = null, + R = vr, + G = vg, + B = vb, + A = va, + }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationFloat.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationFloat.cs new file mode 100644 index 000000000..3b35dee5a --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationFloat.cs @@ -0,0 +1,103 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimVariationFloat +{ + public ImAnimVariationMode Mode; + public float Amount; + public float MinClamp; + public float MaxClamp; + public uint Seed; + public delegate* unmanaged[Cdecl] Callback; + public void* User; + + public static ImAnimVariationFloat None => new() + { + Mode = ImAnimVariationMode.None, + Amount = 0, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationFloat Inc(float amt) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = amt, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationFloat Dec(float amt) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = amt, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationFloat Mul(float f) => new() + { + Mode = ImAnimVariationMode.Multiply, + Amount = f, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationFloat Rand(float r) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = r, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationFloat RandAbs(float r) => new() + { + Mode = ImAnimVariationMode.RandomAbs, + Amount = r, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationFloat PingPong(float amt) => new() + { + Mode = ImAnimVariationMode.PingPong, + Amount = amt, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationFloat Fn(ImAnim.VariationFloatFn fn, void* userData = null) => new() + { + Mode = ImAnimVariationMode.Callback, + Amount = 0, + MinClamp = float.MinValue, + MaxClamp = float.MaxValue, + Seed = 0, + Callback = (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), + User = userData + }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationInt.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationInt.cs new file mode 100644 index 000000000..f3a5a7d08 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationInt.cs @@ -0,0 +1,92 @@ +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimVariationInt +{ + public ImAnimVariationMode Mode; + public int Amount; + public int MinClamp; + public int MaxClamp; + public uint Seed; + public delegate* unmanaged[Cdecl] Callback; + public void* User; + + public static ImAnimVariationInt None => new() + { + Mode = ImAnimVariationMode.None, + Amount = 0, + MinClamp = int.MinValue, + MaxClamp = int.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationInt Inc(int amt) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = amt, + MinClamp = int.MinValue, + MaxClamp = int.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationInt Dec(int amt) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = amt, + MinClamp = int.MinValue, + MaxClamp = int.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationInt Mul(int f) => new() + { + Mode = ImAnimVariationMode.Multiply, + Amount = f, + MinClamp = int.MinValue, + MaxClamp = int.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationInt Rand(int r) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = r, + MinClamp = int.MinValue, + MaxClamp = int.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationInt RandAbs(int r) => new() + { + Mode = ImAnimVariationMode.RandomAbs, + Amount = r, + MinClamp = int.MinValue, + MaxClamp = int.MaxValue, + Seed = 0, + Callback = null, + User = null + }; + + public static ImAnimVariationInt Fn(ImAnim.VariationIntFn fn, void* userData = null) => new() + { + Mode = ImAnimVariationMode.Callback, + Amount = 0, + MinClamp = int.MinValue, + MaxClamp = int.MaxValue, + Seed = 0, + Callback = (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), + User = userData + }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec2.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec2.cs new file mode 100644 index 000000000..d0b16e64f --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec2.cs @@ -0,0 +1,149 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimVariationVec2 +{ + public ImAnimVariationMode Mode; + public Vector2 Amount; + public Vector2 MinClamp; + public Vector2 MaxClamp; + public uint Seed; + public delegate* unmanaged[Cdecl] Callback; + public void* User; + public ImAnimVariationFloat X; + public ImAnimVariationFloat Y; + + public static ImAnimVariationVec2 None => new() + { + Mode = ImAnimVariationMode.None, + Amount = Vector2.Zero, + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Inc(Vector2 amt) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = amt, + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Inc(float x, float y) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = new Vector2(x, y), + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Dec(Vector2 amt) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = amt, + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Dec(float x, float y) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = new Vector2(x, y), + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Mul(float f) => new() + { + Mode = ImAnimVariationMode.Multiply, + Amount = new Vector2(f), + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Rand(Vector2 amt) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = amt, + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Rand(float x, float y) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = new Vector2(x, y), + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + // TODO: iam_variation_vec2_fn + public static ImAnimVariationVec2 Fn(ImAnim.VariationVec2Fn fn, void* userData = null) => new() + { + Mode = ImAnimVariationMode.Callback, + Amount = Vector2.Zero, + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), + User = userData, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec2 Axis(ImAnimVariationFloat vx, ImAnimVariationFloat vy) => new() + { + Mode = ImAnimVariationMode.None, + Amount = Vector2.Zero, + MinClamp = new Vector2(float.MinValue), + MaxClamp = new Vector2(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = vx, + Y = vy, + }; +} diff --git a/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec4.cs b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec4.cs new file mode 100644 index 000000000..941d6af16 --- /dev/null +++ b/imgui/Dalamud.Bindings.ImAnim/Structs/ImAnimVariationVec4.cs @@ -0,0 +1,170 @@ +using System.Numerics; +using System.Runtime.InteropServices; + +namespace Dalamud.Bindings.ImAnim; + +[StructLayout(LayoutKind.Sequential)] +public unsafe struct ImAnimVariationVec4 +{ + public ImAnimVariationMode Mode; + public Vector4 Amount; + public Vector4 MinClamp; + public Vector4 MaxClamp; + public uint Seed; + public delegate* unmanaged[Cdecl] Callback; + public void* User; + public ImAnimVariationFloat X; + public ImAnimVariationFloat Y; + public ImAnimVariationFloat Z; + public ImAnimVariationFloat W; + + public static ImAnimVariationVec4 None => new() + { + Mode = ImAnimVariationMode.None, + Amount = Vector4.Zero, + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Inc(Vector4 amt) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = amt, + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Inc(float x, float y, float z, float w) => new() + { + Mode = ImAnimVariationMode.Increment, + Amount = new Vector4(x, y, z, w), + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Dec(Vector4 amt) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = amt, + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Dec(float x, float y, float z, float w) => new() + { + Mode = ImAnimVariationMode.Decrement, + Amount = new Vector4(x, y, z, w), + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Mul(float f) => new() + { + Mode = ImAnimVariationMode.Multiply, + Amount = new Vector4(f), + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Rand(Vector4 amt) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = amt, + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Rand(float x, float y, float z, float w) => new() + { + Mode = ImAnimVariationMode.Random, + Amount = new Vector4(x, y, z, w), + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Fn(ImAnim.VariationVec4Fn fn, void* userData = null) => new() + { + Mode = ImAnimVariationMode.Callback, + Amount = Vector4.Zero, + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = (delegate* unmanaged[Cdecl])Marshal.GetFunctionPointerForDelegate(fn), + User = userData, + X = ImAnimVariationFloat.None, + Y = ImAnimVariationFloat.None, + Z = ImAnimVariationFloat.None, + W = ImAnimVariationFloat.None, + }; + + public static ImAnimVariationVec4 Axis(ImAnimVariationFloat vx, ImAnimVariationFloat vy, ImAnimVariationFloat vz, ImAnimVariationFloat vw) => new() + { + Mode = ImAnimVariationMode.None, + Amount = Vector4.Zero, + MinClamp = new Vector4(float.MinValue), + MaxClamp = new Vector4(float.MaxValue), + Seed = 0, + Callback = null, + User = null, + X = vx, + Y = vy, + Z = vz, + W = vw, + }; +} diff --git a/lib/ImAnim b/lib/ImAnim new file mode 160000 index 000000000..2d22447c6 --- /dev/null +++ b/lib/ImAnim @@ -0,0 +1 @@ +Subproject commit 2d22447c633d0104ac0d68391fd20077d0070369