From 8f94aea56ab308a9efe7e790677751c45ac047ff Mon Sep 17 00:00:00 2001 From: Peter Slattery Date: Sat, 29 Feb 2020 15:43:06 -0800 Subject: [PATCH] Implemented Snapping Animation Clips --- src/animation/foldhaus_animation.h | 6 -- .../foldhaus_panel_animation_timeline.h | 68 +++++++++++++++---- todo.txt | 6 +- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/animation/foldhaus_animation.h b/src/animation/foldhaus_animation.h index 033ee22..be31d93 100644 --- a/src/animation/foldhaus_animation.h +++ b/src/animation/foldhaus_animation.h @@ -3,12 +3,6 @@ // Author: Peter Slattery // Creation Date: 2020-01-01 // -// TODO -// [] - animation blending -// [] - delete a layer -// [] - will need a way to create an empty layer -// [] - get a list of all animation procs - #ifndef FOLDHAUS_ANIMATION #define ANIMATION_PROC(name) void name(assembly* Assembly, r32 Time) diff --git a/src/panels/foldhaus_panel_animation_timeline.h b/src/panels/foldhaus_panel_animation_timeline.h index a80c9d2..ffcb45c 100644 --- a/src/panels/foldhaus_panel_animation_timeline.h +++ b/src/panels/foldhaus_panel_animation_timeline.h @@ -5,14 +5,6 @@ // #ifndef FOLDHAUS_PANEL_ANIMATION_TIMELINE_H -// TODO -// [x] - Moving animation blocks -// [x] - dragging beginning and end of time blocks -// [] - creating a timeblock with a specific animation -// [x] - play, pause, stop, -// [] - setting the start and end of the animation system -// [] - displaying multiple layers - inline r32 GetTimeFromPointInAnimationPanel(v2 Point, rect PanelBounds, s32 StartFrame, s32 EndFrame, r32 SecondsPerFrame) { @@ -138,6 +130,18 @@ OPERATION_STATE_DEF(drag_animation_clip_state) r32 SelectedClip_InitialEndTime; }; +internal r32 +AttemptToSnapPosition(r32 Snapping, r32 SnapTo) +{ + r32 Result = Snapping; + r32 SnapDistance = .25f; + if (GSAbs(Snapping - SnapTo) <= SnapDistance) + { + Result = SnapTo; + } + return Result; +} + OPERATION_RENDER_PROC(UpdateDragAnimationClip) { drag_animation_clip_state* OpState = (drag_animation_clip_state*)Operation.OpStateMemory; @@ -151,18 +155,58 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip) animation_block* AnimationBlock = State->AnimationSystem.Blocks.GetElementWithHandle(State->SelectedAnimationBlockHandle); + // TODO(Peter): This should really be in pixels so we can zoom in and out on the timeline + r32 SnapDistance = .25f; if (GSAbs(Mouse.DownPos.x - ClipInitialStartTimeXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE) { - AnimationBlock->StartTime = OpState->SelectedClip_InitialStartTime + TimeOffset; + r32 NewStartTime = OpState->SelectedClip_InitialStartTime + TimeOffset; + for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++) + { + gs_list_entry* OtherBlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i); + if (OtherBlockEntry->Free.NextFreeEntry != 0) { continue; } + animation_block OtherBlock = OtherBlockEntry->Value; + NewStartTime = AttemptToSnapPosition(NewStartTime, OtherBlock.EndTime); + } + AnimationBlock->StartTime = NewStartTime; } else if (GSAbs(Mouse.DownPos.x - ClipInitialEndTimeXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE) { - AnimationBlock->EndTime = OpState->SelectedClip_InitialEndTime + TimeOffset; + r32 NewEndTime = OpState->SelectedClip_InitialEndTime + TimeOffset; + for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++) + { + gs_list_entry* OtherBlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i); + if (OtherBlockEntry->Free.NextFreeEntry != 0) { continue; } + animation_block OtherBlock = OtherBlockEntry->Value; + NewEndTime = AttemptToSnapPosition(NewEndTime, OtherBlock.StartTime); + } + AnimationBlock->EndTime = NewEndTime; } else { - AnimationBlock->StartTime = OpState->SelectedClip_InitialStartTime + TimeOffset; - AnimationBlock->EndTime = OpState->SelectedClip_InitialEndTime + TimeOffset; + r32 NewStartTime = OpState->SelectedClip_InitialStartTime + TimeOffset; + r32 NewEndTime = OpState->SelectedClip_InitialEndTime + TimeOffset; + for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++) + { + gs_list_entry* OtherBlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i); + if (OtherBlockEntry->Free.NextFreeEntry != 0) { continue; } + animation_block OtherBlock = OtherBlockEntry->Value; + + r32 SnapAmount = 0; + if (TimeOffset > 0) + { + r32 FinalEndTime = AttemptToSnapPosition(NewEndTime, OtherBlock.StartTime); + SnapAmount = FinalEndTime - NewEndTime; + } + else if (TimeOffset < 0) + { + r32 FinalStartTime = AttemptToSnapPosition(NewStartTime, OtherBlock.EndTime); + SnapAmount = FinalStartTime - NewStartTime; + } + NewEndTime += SnapAmount; + NewStartTime += SnapAmount; + } + AnimationBlock->StartTime = NewStartTime; + AnimationBlock->EndTime = NewEndTime; } } diff --git a/todo.txt b/todo.txt index c6a27ca..51ebbbc 100644 --- a/todo.txt +++ b/todo.txt @@ -64,11 +64,15 @@ Ground Up Reengineering - debug capabilities (toggle strip/led/universe colors) - Animation System - - snapping clips + x snapping clips + - zoom in and out - blending between animation - layers + - display more than one layer + - add/remove layers - layer masks by sculpture - blend modes + - setting start and end of timeline (how long is a loop) - Node System - automatic node layout