From 76d27e3b5794544d585ccb1f75de89eec772f33a Mon Sep 17 00:00:00 2001 From: Peter Slattery Date: Thu, 26 Dec 2019 18:40:14 -0800 Subject: [PATCH] Fixed a bug where unloading assemblies caused a crash in the test patterns. Fixed another bug caused by not initializing dmx buffers linked lists to zero. --- src/animation/foldhaus_animation.h | 5 +- src/foldhaus_app.cpp | 49 ++++---- src/foldhaus_app.h | 96 ++++++++++----- src/foldhaus_assembly.cpp | 12 +- src/gs_array.h | 11 +- .../foldhaus_panel_animation_timeline.h | 111 ++++++++++++------ src/panels/foldhaus_panel_hierarchy.h | 2 +- 7 files changed, 185 insertions(+), 101 deletions(-) diff --git a/src/animation/foldhaus_animation.h b/src/animation/foldhaus_animation.h index 73aedeb..003ef2d 100644 --- a/src/animation/foldhaus_animation.h +++ b/src/animation/foldhaus_animation.h @@ -5,7 +5,7 @@ // [] - will need a way to create an empty layer // [] - get a list of all animation procs -#define ANIMATION_PROC(name) void name(app_state* State, r32 Time) +#define ANIMATION_PROC(name) void name(assembly* Assembly, r32 Time) typedef ANIMATION_PROC(animation_proc); struct animation_block @@ -46,7 +46,8 @@ u32 BlocksCount; b32 TimelineShouldAdvance; // :Temporary - r32 AnimationEnd; + r32 AnimationStart; +r32 AnimationEnd; }; internal b32 diff --git a/src/foldhaus_app.cpp b/src/foldhaus_app.cpp index 8148b2c..c0e8161 100644 --- a/src/foldhaus_app.cpp +++ b/src/foldhaus_app.cpp @@ -275,27 +275,22 @@ INITIALIZE_APPLICATION(InitializeApplication) { // MODES PLAYGROUND InitializeAnimationSystem(&State->AnimationSystem); - State->AnimationSystem.SecondsPerFrame = 1.f / 24.f; - - animation_block BlockZero = {0}; - BlockZero.StartTime = 0; - BlockZero.EndTime = 2; - BlockZero.Proc = TestPatternOne; - AddAnimationBlock(BlockZero, &State->AnimationSystem); +State->AnimationSystem.SecondsPerFrame = 1.f / 24.f; animation_block BlockOne = {0}; - BlockOne.StartTime = 3; - BlockOne.EndTime = 5; + BlockOne.StartTime = 0; + BlockOne.EndTime = 8; BlockOne.Proc = TestPatternTwo; AddAnimationBlock(BlockOne, &State->AnimationSystem); animation_block BlockTwo = {0}; - BlockTwo.StartTime = 5; - BlockTwo.EndTime = 8; + BlockTwo.StartTime = 8; + BlockTwo.EndTime = 15; BlockTwo.Proc = TestPatternThree; AddAnimationBlock(BlockTwo, &State->AnimationSystem); - State->AnimationSystem.AnimationEnd = 10; + State->AnimationSystem.AnimationStart = 0; + State->AnimationSystem.AnimationEnd = 15; } // End Animation Playground @@ -303,8 +298,6 @@ INITIALIZE_APPLICATION(InitializeApplication) InitializePanelLayout(&State->PanelLayout); panel* Panel = TakeNewPanel(&State->PanelLayout); SetPanelDefinition(Panel, 0); - SplitPanelVertically(Panel, .5f, v2{0, 0}, v2{Context.WindowWidth, Context.WindowHeight}, &State->PanelLayout); - SetPanelDefinition(&Panel->Right->Panel, 1); } // End Panels Playground } @@ -365,10 +358,11 @@ CreateDMXBuffers(assembly Assembly, s32 BufferHeaderSize, memory_arena* Arena) leds_in_universe_range LEDUniverseRange = Assembly.LEDUniverseMap[Range]; dmx_buffer_list* NewBuffer = PushStruct(Arena, dmx_buffer_list); - NewBuffer->Buffer.Universe = LEDUniverseRange.Universe; +NewBuffer->Buffer.Universe = LEDUniverseRange.Universe; NewBuffer->Buffer.Base = PushArray(Arena, u8, BufferSize); NewBuffer->Buffer.TotalSize = BufferSize; NewBuffer->Buffer.HeaderSize = BufferHeaderSize; + NewBuffer->Next = 0; // Append if (!Result) { @@ -433,7 +427,12 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se if (State->AnimationSystem.Time >= Block.StartTime && State->AnimationSystem.Time <= Block.EndTime) { - Block.Proc(State, FrameTime - Block.StartTime); + for (s32 j = 0; j < State->ActiveAssemblyIndecies.Used; j++) + { + array_entry_handle* AssemblyHandle = GetElementAtIndex(j, State->ActiveAssemblyIndecies); + assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList); + Block.Proc(Assembly, FrameTime - Block.StartTime); + } } } } @@ -441,12 +440,17 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se s32 HeaderSize = State->NetworkProtocolHeaderSize; dmx_buffer_list* DMXBuffers = 0; + if (State->ActiveAssemblyIndecies.Used > 1) + { + s32 f = 4; + } + for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++) { - array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies); - assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList); - dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(Assembly, HeaderSize, &State->Transient); - DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers); + array_entry_handle* AssemblyHandle = GetElementAtIndex(i, State->ActiveAssemblyIndecies); + assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList); + dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(*Assembly, HeaderSize, &State->Transient); + DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers); } DEBUG_IF(GlobalDebugServices->Interface.SendSACNData) @@ -566,9 +570,10 @@ PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHe { DEBUG_TRACK_SCOPE(OverflowChecks); AssertAllocationsNoOverflow(State->Permanent); - for (s32 i = 0; i < State->AssemblyList.Used; i++) + for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++) { - assembly* Assembly = GetElementAtIndex(i, State->AssemblyList); + array_entry_handle* AssemblyHandle = GetElementAtIndex(i, State->ActiveAssemblyIndecies); + assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList); AssertAllocationsNoOverflow(Assembly->Arena); } } diff --git a/src/foldhaus_app.h b/src/foldhaus_app.h index 1318f21..d27a06f 100644 --- a/src/foldhaus_app.h +++ b/src/foldhaus_app.h @@ -74,51 +74,85 @@ internal void OpenColorPicker(app_state* State, v4* Address); // BEGIN TEMPORARY PATTERNS internal void -TestPatternOne(app_state* State, r32 Time) +TestPatternOne(assembly* Assembly, r32 Time) { - array_entry_handle TestAssemblyHandle = *GetElementAtIndex(0, State->ActiveAssemblyIndecies); - assembly TestAssembly = *GetElementWithHandle(TestAssemblyHandle, State->AssemblyList); - for (s32 Range = 0; Range < TestAssembly.LEDUniverseMapCount; Range++) + for (s32 Range = 0; Range < Assembly->LEDUniverseMapCount; Range++) { - leds_in_universe_range LEDUniverseRange = TestAssembly.LEDUniverseMap[Range]; + leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range]; for (s32 LEDIdx = LEDUniverseRange.RangeStart; LEDIdx < LEDUniverseRange.RangeOnePastLast; LEDIdx++) { - led LED = TestAssembly.LEDs[LEDIdx]; - TestAssembly.Colors[LED.Index].R = 255; - TestAssembly.Colors[LED.Index].B = 255; - TestAssembly.Colors[LED.Index].G = 255; + led LED = Assembly->LEDs[LEDIdx]; + Assembly->Colors[LED.Index].R = 255; + Assembly->Colors[LED.Index].B = 255; + Assembly->Colors[LED.Index].G = 255; + } } - } } internal void -TestPatternTwo(app_state* State, r32 Time) +TestPatternTwo(assembly* Assembly, r32 Time) { - if (Time > 2 * PI * 100) { Time = 0; } - r32 SinAdjusted = 0.5f + (GSSin(Time * 0.01f) * .5f); - u8 Brightness = (u8)(GSClamp01(SinAdjusted) * 255); + r32 PeriodicTime = (Time / PI) * 2; + + r32 ZeroOneSin = (GSSin(PeriodicTime) * .5f) + .5f; +r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f; + pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) }; - array_entry_handle TestAssemblyHandle = *GetElementAtIndex(0, State->ActiveAssemblyIndecies); - assembly TestAssembly = *GetElementWithHandle(TestAssemblyHandle, State->AssemblyList); - for (s32 Range = 0; Range < TestAssembly.LEDUniverseMapCount; Range++) + v4 Center = v4{0, 0, 0, 1}; + r32 ThetaZ = Time / 2; + v4 Normal = v4{GSCos(ThetaZ), 0, GSSin(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1 + v4 Right = Cross(Normal, v4{0, 1, 0, 0}); + + v4 FrontCenter = Center + (Normal * 25); + v4 BackCenter = Center - (Normal * 25); + + r32 OuterRadiusSquared = 1000000; + r32 InnerRadiusSquared = 0; + +for (s32 Range = 0; Range < Assembly->LEDUniverseMapCount; Range++) { - leds_in_universe_range LEDUniverseRange = TestAssembly.LEDUniverseMap[Range]; - for (s32 LEDIdx = LEDUniverseRange.RangeStart; + leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range]; +for (s32 LEDIdx = LEDUniverseRange.RangeStart; LEDIdx < LEDUniverseRange.RangeOnePastLast; LEDIdx++) { - led LED = TestAssembly.LEDs[LEDIdx]; - TestAssembly.Colors[LED.Index].R = Brightness; - TestAssembly.Colors[LED.Index].B = 0; - TestAssembly.Colors[LED.Index].G = Brightness; + led LED = Assembly->LEDs[LEDIdx]; + + v4 Position = LED.Position; + + v4 ToFront = Position + FrontCenter; + v4 ToBack = Position + BackCenter; + + r32 ToFrontDotNormal = Dot(ToFront, Normal); + r32 ToBackDotNormal = Dot(ToBack, Normal); + + ToFrontDotNormal = GSClamp01(ToFrontDotNormal * 1000); + ToBackDotNormal = GSClamp01(ToBackDotNormal * 1000); + + r32 SqDistToCenter = MagSqr(Position); + if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared) + { + if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0)) + { + Assembly->Colors[LED.Index] = Color; + } + else + { + Assembly->Colors[LED.Index] = {}; + } + } +else + { + Assembly->Colors[LED.Index] = {}; + } } } } internal void -TestPatternThree(app_state* State, r32 Time) +TestPatternThree(assembly* Assembly, r32 Time) { r32 GreenSize = 20.0f; r32 BlueSize = 25.0f; @@ -128,16 +162,14 @@ r32 GreenSize = 20.0f; r32 BluePosition = -BlueSize + (Time * 25); r32 RedPosition = (100 + RedSize) + (Time * -35); - array_entry_handle TestAssemblyHandle = *GetElementAtIndex(0, State->ActiveAssemblyIndecies); - assembly TestAssembly = *GetElementWithHandle(TestAssemblyHandle, State->AssemblyList); - for (s32 Range = 0; Range < TestAssembly.LEDUniverseMapCount; Range++) + for (s32 Range = 0; Range < Assembly->LEDUniverseMapCount; Range++) { - leds_in_universe_range LEDUniverseRange = TestAssembly.LEDUniverseMap[Range]; + leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range]; for (s32 LEDIdx = LEDUniverseRange.RangeStart; LEDIdx < LEDUniverseRange.RangeOnePastLast; LEDIdx++) { - led LED = TestAssembly.LEDs[LEDIdx]; + led LED = Assembly->LEDs[LEDIdx]; u8 Red = 0; u8 Green = 0; u8 Blue = 0; @@ -154,9 +186,9 @@ r32 GreenSize = 20.0f; r32 RedBrightness = GSClamp(0.0f, RedSize - RedDistance, RedSize) / RedSize; Red = (u8)(RedBrightness * 255); - TestAssembly.Colors[LED.Index].R = Red; - TestAssembly.Colors[LED.Index].B = Blue; - TestAssembly.Colors[LED.Index].G = Green; + Assembly->Colors[LED.Index].R = Red; + Assembly->Colors[LED.Index].B = Blue; + Assembly->Colors[LED.Index].G = Green; } } } diff --git a/src/foldhaus_assembly.cpp b/src/foldhaus_assembly.cpp index f9c700f..4a39d04 100644 --- a/src/foldhaus_assembly.cpp +++ b/src/foldhaus_assembly.cpp @@ -10,7 +10,7 @@ GetAssemblyMemorySizeFromDefinition(assembly_definition Definition, string Name) internal assembly ConstructAssemblyFromDefinition (assembly_definition Definition, string AssemblyName, - v3 RootPosition, + v4 RootPosition, r32 Scale, memory_arena Arena) { @@ -43,8 +43,8 @@ ConstructAssemblyFromDefinition (assembly_definition Definition, // now. The assert is to remind you to create more cases when necessary Assert(StripDef.InterpolationType == StripInterpolate_Points); - v4 WS_StripStart = V4(StripDef.InterpolatePositionStart * Scale, 1); - v4 WS_StripEnd = V4(StripDef.InterpolatePositionEnd * Scale, 1); + v4 WS_StripStart = RootPosition + V4(StripDef.InterpolatePositionStart * Scale, 1); + v4 WS_StripEnd = RootPosition + V4(StripDef.InterpolatePositionEnd * Scale, 1); s32 LEDsInStripCount = StripDef.LEDsPerStrip; Assert(Assembly.LEDCount + LEDsInStripCount <= Definition.TotalLEDCount); @@ -63,6 +63,9 @@ ConstructAssemblyFromDefinition (assembly_definition Definition, return Assembly; } +static v4 TempAssemblyOffsets[] = { v4{0, 0, 0, 0}, v4{250, 0, 75, 0}, v4{-250, 0, 75, 0} }; +s32 TempAssemblyOffsetsCount = 3; + internal void LoadAssembly (app_state* State, context Context, char* Path) { @@ -82,9 +85,10 @@ LoadAssembly (app_state* State, context Context, char* Path) AssemblyArena.Alloc = (gs_memory_alloc*)Context.PlatformAlloc; AssemblyArena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc; + v4 Offset = TempAssemblyOffsets[State->ActiveAssemblyIndecies.Used % TempAssemblyOffsetsCount]; assembly NewAssembly = ConstructAssemblyFromDefinition(AssemblyDefinition, FileName, - v3{0, 0, 0}, + Offset, Scale, AssemblyArena); array_entry_handle NewAssemblyHandle = PushElement(NewAssembly, &State->AssemblyList); diff --git a/src/gs_array.h b/src/gs_array.h index 6fd0b47..37c9855 100644 --- a/src/gs_array.h +++ b/src/gs_array.h @@ -147,7 +147,6 @@ RemoveElementAtIndex (s32 Index, element_type##_array* Buffer) \ Entry->Free.Next = Buffer->FreeList.Next; \ Buffer->FreeList.Next = &Entry->Free; \ \ - --Buffer->Used; \ } \ // END OF CRAZY MACRO @@ -183,9 +182,13 @@ GrowBuffer(element_type##_contiguous_array* Buffer) \ \ internal element_type* \ GetElementAtIndex (s32 Index, element_type##_contiguous_array Buffer) \ -{ \ - bucket_index BucketIndex = GetBucketIndexForIndex(Index, Buffer.BucketSize); \ - element_type* Entry = Buffer.Buckets[BucketIndex.Bucket] + BucketIndex.IndexInBucket; \ + { \ + element_type* Entry = 0; \ + if (Index <= Buffer.Used) \ + { \ +bucket_index BucketIndex = GetBucketIndexForIndex(Index, Buffer.BucketSize); \ + Entry = Buffer.Buckets[BucketIndex.Bucket] + BucketIndex.IndexInBucket; \ + } \ return Entry; \ } \ \ diff --git a/src/panels/foldhaus_panel_animation_timeline.h b/src/panels/foldhaus_panel_animation_timeline.h index 829e1a6..5217815 100644 --- a/src/panels/foldhaus_panel_animation_timeline.h +++ b/src/panels/foldhaus_panel_animation_timeline.h @@ -17,35 +17,31 @@ PANEL_CLEANUP_PROC(AnimationTimeline_Cleanup) } -internal animation_block_handle -DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 EndFrame, v2 PanelMin, v2 PanelMax, animation_block_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse) +internal r32 +DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBuffer, s32 StartFrame, s32 EndFrame, v2 PanelMin, v2 PanelMax, interface_config Interface, mouse_state Mouse) { - string TempString = MakeString(PushArray(&State->Transient, char, 256), 256); -s32 FrameCount = EndFrame - StartFrame; - - animation_block_handle Result = SelectedBlockHandle; + MakeStringBuffer(TempString, 256); - r32 AnimationPanelHeight = PanelMax.y - PanelMin.y; - r32 AnimationPanelWidth = PanelMax.x - PanelMin.x; - PushRenderQuad2D(RenderBuffer, PanelMin, PanelMax, v4{.22f, .22f, .22f, 1.f}); + s32 FrameCount = EndFrame - StartFrame; - // Frame Bar r32 FrameBarHeight = 24; v2 FrameBarMin = v2{PanelMin.x, PanelMax.y - FrameBarHeight}; v2 FrameBarMax = PanelMax; + PushRenderQuad2D(RenderBuffer, FrameBarMin, FrameBarMax, v4{.16f, .16f, .16f, 1.f}); -// Mouse clicked inside frame nubmer bar -> change current frame on timeline + // Mouse clicked inside frame nubmer bar -> change current frame on timeline if (MouseButtonHeldDown(Mouse.LeftButtonState) && PointIsInRange(Mouse.DownPos, FrameBarMin, FrameBarMax)) { r32 MouseX = Mouse.DownPos.x; - r32 MousePercentX = (MouseX - FrameBarMin.x) / (FrameBarMax.x - FrameBarMin.y); - s32 MouseFrame = (s32)((MousePercentX * FrameCount) + StartFrame); - r32 MouseFrameTime = (r32)MouseFrame * AnimationSystem->SecondsPerFrame; - AnimationSystem->Time = MouseFrameTime; + r32 StartFrameTime = (r32)StartFrame * AnimationSystem->SecondsPerFrame; + r32 EndFrameTime = (r32)EndFrame * AnimationSystem->SecondsPerFrame; + r32 MouseTime = GSRemap(MouseX, FrameBarMin.x, FrameBarMax.x, StartFrameTime, EndFrameTime); + AnimationSystem->Time = MouseTime; } + // Frame Ticks for (s32 f = 0; f < FrameCount; f += 10) { s32 Frame = StartFrame + f; @@ -54,7 +50,7 @@ s32 FrameCount = EndFrame - StartFrame; r32 FramePercent = (r32)f / (r32)FrameCount; r32 FrameX = GSLerp(PanelMin.x, PanelMax.x, FramePercent); v2 FrameTextPos = v2{FrameX, FrameBarMin.y + 2}; - DrawString(RenderBuffer, TempString, State->Interface.Font, FrameTextPos, WhiteV4); + DrawString(RenderBuffer, TempString, Interface.Font, FrameTextPos, WhiteV4); // Frame Vertical Slices v2 LineTop = v2{FrameX, FrameBarMin.y}; @@ -62,11 +58,65 @@ s32 FrameCount = EndFrame - StartFrame; PushRenderQuad2D(RenderBuffer, LineTop, LineBottom, v4{.16f, .16f, .16f, 1.f}); } + return FrameBarMin.y; +} + +internal rect +DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, r32 SecondsPerFrame, s32 FrameCount, s32 StartFrame, v2 TimelineMin, v2 TimelineMax, render_command_buffer* RenderBuffer) +{ + rect BlockBounds = {}; + + r32 TimelineWidth = TimelineMax.x - TimelineMin.x; + + s32 BlockStartFrame = AnimationBlock.StartTime / SecondsPerFrame; + r32 StartFramePercent = (r32)(BlockStartFrame - StartFrame) / (r32)FrameCount; + r32 StartPosition = TimelineWidth * StartFramePercent; + + s32 BlockEndFrame = AnimationBlock.EndTime / SecondsPerFrame; + r32 EndFramePercent = (r32)(BlockEndFrame - StartFrame) / (r32)FrameCount; + r32 EndPosition = TimelineWidth * EndFramePercent; + + BlockBounds.Min = TimelineMin + v2{StartPosition, 25}; + BlockBounds.Max = TimelineMin + v2{EndPosition, 75}; + + PushRenderQuad2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, BlockColor); + PushRenderBoundingBox2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, 1, WhiteV4); + + return BlockBounds; +} + +internal animation_block_handle +DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 EndFrame, v2 PanelMin, v2 PanelMax, animation_block_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse) +{ + string TempString = MakeString(PushArray(&State->Transient, char, 256), 256); + s32 FrameCount = EndFrame - StartFrame; + + animation_block_handle Result = SelectedBlockHandle; + + r32 AnimationPanelHeight = PanelMax.y - PanelMin.y; + r32 AnimationPanelWidth = PanelMax.x - PanelMin.x; + + { + s32 FirstPlayableFrame = (AnimationSystem->AnimationStart / AnimationSystem->SecondsPerFrame); + s32 LastPlayableFrame = (AnimationSystem->AnimationEnd / AnimationSystem->SecondsPerFrame); + + r32 FirstPlayablePercentX = ((r32)(FirstPlayableFrame - StartFrame) / (r32)FrameCount); + r32 LastPlayablePercentX = ((r32)(LastPlayableFrame - StartFrame) / (r32)FrameCount); + + v2 PlayableMin = v2{(FirstPlayablePercentX * AnimationPanelWidth) + PanelMin.x, PanelMin.y }; + v2 PlayableMax = v2{(LastPlayablePercentX * AnimationPanelWidth) + PanelMin.x, PanelMax.y }; + + PushRenderQuad2D(RenderBuffer, PanelMin, PanelMax, v4{.16f, .16f, .16f, 1.f}); + PushRenderQuad2D(RenderBuffer, PlayableMin, PlayableMax, v4{.22f, .22f, .22f, 1.f}); + } + + r32 FrameBarBottom = DrawFrameBar(AnimationSystem, RenderBuffer, StartFrame, EndFrame, PanelMin, PanelMax, State->Interface, Mouse); + // Animation Blocks v2 TimelineMin = PanelMin; - v2 TimelineMax = v2{PanelMax.x, FrameBarMin.y}; + v2 TimelineMax = v2{PanelMax.x, FrameBarBottom}; b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState); -for (u32 i = 0; i < AnimationSystem->BlocksCount; i++) + for (u32 i = 0; i < AnimationSystem->BlocksCount; i++) { animation_block_entry AnimationBlockEntry = AnimationSystem->Blocks[i]; if (AnimationBlockIsFree(AnimationBlockEntry)) { continue; } @@ -77,27 +127,15 @@ for (u32 i = 0; i < AnimationSystem->BlocksCount; i++) animation_block AnimationBlockAt = AnimationBlockEntry.Block; - s32 BlockStartFrame = AnimationBlockAt.StartTime / AnimationSystem->SecondsPerFrame; - r32 StartFramePercent = (r32)(BlockStartFrame - StartFrame) / (r32)FrameCount; - r32 StartPosition = AnimationPanelWidth * StartFramePercent; - - s32 BlockEndFrame = AnimationBlockAt.EndTime / AnimationSystem->SecondsPerFrame; - r32 EndFramePercent = (r32)(BlockEndFrame - StartFrame) / (r32)FrameCount; - r32 EndPosition = AnimationPanelWidth * EndFramePercent; - - v2 Min = TimelineMin + v2{StartPosition, 25}; - v2 Max = TimelineMin + v2{EndPosition, 75}; - v4 BlockColor = BlackV4; if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle)) { BlockColor = PinkV4; } - PushRenderQuad2D(RenderBuffer, Min, Max, BlockColor); - PushRenderBoundingBox2D(RenderBuffer, Min, Max, 1, WhiteV4); + rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AnimationSystem->SecondsPerFrame, FrameCount, StartFrame, TimelineMin, TimelineMax, RenderBuffer); - if (PointIsInRange(Mouse.Pos, Min, Max) + if (PointIsInRange(Mouse.Pos, BlockBounds.Min, BlockBounds.Max) && MouseButtonTransitionedDown(Mouse.LeftButtonState)) { MouseDownAndNotHandled = false; @@ -114,8 +152,8 @@ for (u32 i = 0; i < AnimationSystem->BlocksCount; i++) } // Time Slider -s32 SliderFrame = AnimationSystem->Time / AnimationSystem->SecondsPerFrame; - r32 TimePercent = (r32)SliderFrame / (r32)EndFrame; + s32 SliderFrame = AnimationSystem->Time / AnimationSystem->SecondsPerFrame; + r32 TimePercent = (r32)(SliderFrame - StartFrame) / (r32)FrameCount; r32 SliderX = PanelMin.x + (AnimationPanelWidth * TimePercent); v2 SliderMin = v2{SliderX, PanelMin.y}; v2 SliderMax = v2{SliderX + 1, PanelMax.y - 25}; @@ -125,7 +163,7 @@ s32 SliderFrame = AnimationSystem->Time / AnimationSystem->SecondsPerFrame; r32 SliderHalfWidth = 10; v2 HeadMin = v2{SliderX - SliderHalfWidth, SliderMax.y}; - v2 HeadMax = v2{SliderX + SliderHalfWidth, SliderMax.y + FrameBarHeight}; + v2 HeadMax = v2{SliderX + SliderHalfWidth, PanelMax.y}; PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor); PrintF(&TempString, "%d", SliderFrame); @@ -158,9 +196,10 @@ PANEL_RENDER_PROC(AnimationTimeline_Render) v2 TimelineMax = v2{PanelMax.x, PanelMax.y - OptionsRowHeight}; if (TimelineMax.y - TimelineMin.y > 0) { + s32 FrameStart = (s32)(State->AnimationSystem.AnimationStart / State->AnimationSystem.SecondsPerFrame); s32 FrameEnd = (s32)(State->AnimationSystem.AnimationEnd / State->AnimationSystem.SecondsPerFrame); SelectedBlockHandle = DrawAnimationTimeline(&State->AnimationSystem, - 0, FrameEnd, + FrameStart - 20, FrameEnd + 20, TimelineMin, TimelineMax, SelectedBlockHandle, RenderBuffer, State, Mouse); diff --git a/src/panels/foldhaus_panel_hierarchy.h b/src/panels/foldhaus_panel_hierarchy.h index db23770..08d8b87 100644 --- a/src/panels/foldhaus_panel_hierarchy.h +++ b/src/panels/foldhaus_panel_hierarchy.h @@ -51,7 +51,7 @@ array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyI if (MouseButtonTransitionedUp(Mouse.LeftButtonState) && PointIsInRange(Mouse.Pos, XLowerLeft, LineMax)) { - UnloadAssembly(i, State, Context); + UnloadAssembly(AssemblyHandle.Index, State, Context); } } else if (i == State->ActiveAssemblyIndecies.Used)