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.
This commit is contained in:
parent
2c6adaeda2
commit
76d27e3b57
|
@ -5,7 +5,7 @@
|
||||||
// [] - will need a way to create an empty layer
|
// [] - will need a way to create an empty layer
|
||||||
// [] - get a list of all animation procs
|
// [] - 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);
|
typedef ANIMATION_PROC(animation_proc);
|
||||||
|
|
||||||
struct animation_block
|
struct animation_block
|
||||||
|
@ -46,6 +46,7 @@ u32 BlocksCount;
|
||||||
b32 TimelineShouldAdvance;
|
b32 TimelineShouldAdvance;
|
||||||
|
|
||||||
// :Temporary
|
// :Temporary
|
||||||
|
r32 AnimationStart;
|
||||||
r32 AnimationEnd;
|
r32 AnimationEnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -277,25 +277,20 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
InitializeAnimationSystem(&State->AnimationSystem);
|
InitializeAnimationSystem(&State->AnimationSystem);
|
||||||
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
||||||
|
|
||||||
animation_block BlockZero = {0};
|
|
||||||
BlockZero.StartTime = 0;
|
|
||||||
BlockZero.EndTime = 2;
|
|
||||||
BlockZero.Proc = TestPatternOne;
|
|
||||||
AddAnimationBlock(BlockZero, &State->AnimationSystem);
|
|
||||||
|
|
||||||
animation_block BlockOne = {0};
|
animation_block BlockOne = {0};
|
||||||
BlockOne.StartTime = 3;
|
BlockOne.StartTime = 0;
|
||||||
BlockOne.EndTime = 5;
|
BlockOne.EndTime = 8;
|
||||||
BlockOne.Proc = TestPatternTwo;
|
BlockOne.Proc = TestPatternTwo;
|
||||||
AddAnimationBlock(BlockOne, &State->AnimationSystem);
|
AddAnimationBlock(BlockOne, &State->AnimationSystem);
|
||||||
|
|
||||||
animation_block BlockTwo = {0};
|
animation_block BlockTwo = {0};
|
||||||
BlockTwo.StartTime = 5;
|
BlockTwo.StartTime = 8;
|
||||||
BlockTwo.EndTime = 8;
|
BlockTwo.EndTime = 15;
|
||||||
BlockTwo.Proc = TestPatternThree;
|
BlockTwo.Proc = TestPatternThree;
|
||||||
AddAnimationBlock(BlockTwo, &State->AnimationSystem);
|
AddAnimationBlock(BlockTwo, &State->AnimationSystem);
|
||||||
|
|
||||||
State->AnimationSystem.AnimationEnd = 10;
|
State->AnimationSystem.AnimationStart = 0;
|
||||||
|
State->AnimationSystem.AnimationEnd = 15;
|
||||||
} // End Animation Playground
|
} // End Animation Playground
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,8 +298,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
InitializePanelLayout(&State->PanelLayout);
|
InitializePanelLayout(&State->PanelLayout);
|
||||||
panel* Panel = TakeNewPanel(&State->PanelLayout);
|
panel* Panel = TakeNewPanel(&State->PanelLayout);
|
||||||
SetPanelDefinition(Panel, 0);
|
SetPanelDefinition(Panel, 0);
|
||||||
SplitPanelVertically(Panel, .5f, v2{0, 0}, v2{Context.WindowWidth, Context.WindowHeight}, &State->PanelLayout);
|
|
||||||
SetPanelDefinition(&Panel->Right->Panel, 1);
|
|
||||||
} // End Panels Playground
|
} // End Panels Playground
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,6 +362,7 @@ CreateDMXBuffers(assembly Assembly, s32 BufferHeaderSize, memory_arena* Arena)
|
||||||
NewBuffer->Buffer.Base = PushArray(Arena, u8, BufferSize);
|
NewBuffer->Buffer.Base = PushArray(Arena, u8, BufferSize);
|
||||||
NewBuffer->Buffer.TotalSize = BufferSize;
|
NewBuffer->Buffer.TotalSize = BufferSize;
|
||||||
NewBuffer->Buffer.HeaderSize = BufferHeaderSize;
|
NewBuffer->Buffer.HeaderSize = BufferHeaderSize;
|
||||||
|
NewBuffer->Next = 0;
|
||||||
|
|
||||||
// Append
|
// Append
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
|
@ -433,7 +427,12 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se
|
||||||
if (State->AnimationSystem.Time >= Block.StartTime
|
if (State->AnimationSystem.Time >= Block.StartTime
|
||||||
&& State->AnimationSystem.Time <= Block.EndTime)
|
&& 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,11 +440,16 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se
|
||||||
|
|
||||||
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
||||||
dmx_buffer_list* DMXBuffers = 0;
|
dmx_buffer_list* DMXBuffers = 0;
|
||||||
|
if (State->ActiveAssemblyIndecies.Used > 1)
|
||||||
|
{
|
||||||
|
s32 f = 4;
|
||||||
|
}
|
||||||
|
|
||||||
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
|
||||||
{
|
{
|
||||||
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
array_entry_handle* AssemblyHandle = GetElementAtIndex(i, State->ActiveAssemblyIndecies);
|
||||||
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
|
assembly* Assembly = GetElementWithHandle(*AssemblyHandle, State->AssemblyList);
|
||||||
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(Assembly, HeaderSize, &State->Transient);
|
dmx_buffer_list* NewDMXBuffers = CreateDMXBuffers(*Assembly, HeaderSize, &State->Transient);
|
||||||
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
|
DMXBuffers = DMXBufferListAppend(DMXBuffers, NewDMXBuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,9 +570,10 @@ PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHe
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_SCOPE(OverflowChecks);
|
DEBUG_TRACK_SCOPE(OverflowChecks);
|
||||||
AssertAllocationsNoOverflow(State->Permanent);
|
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);
|
AssertAllocationsNoOverflow(Assembly->Arena);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,51 +74,85 @@ internal void OpenColorPicker(app_state* State, v4* Address);
|
||||||
|
|
||||||
// BEGIN TEMPORARY PATTERNS
|
// BEGIN TEMPORARY PATTERNS
|
||||||
internal void
|
internal void
|
||||||
TestPatternOne(app_state* State, r32 Time)
|
TestPatternOne(assembly* Assembly, r32 Time)
|
||||||
{
|
{
|
||||||
array_entry_handle TestAssemblyHandle = *GetElementAtIndex(0, State->ActiveAssemblyIndecies);
|
for (s32 Range = 0; Range < Assembly->LEDUniverseMapCount; Range++)
|
||||||
assembly TestAssembly = *GetElementWithHandle(TestAssemblyHandle, State->AssemblyList);
|
|
||||||
for (s32 Range = 0; Range < TestAssembly.LEDUniverseMapCount; Range++)
|
|
||||||
{
|
{
|
||||||
leds_in_universe_range LEDUniverseRange = TestAssembly.LEDUniverseMap[Range];
|
leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range];
|
||||||
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
||||||
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
||||||
LEDIdx++)
|
LEDIdx++)
|
||||||
{
|
{
|
||||||
led LED = TestAssembly.LEDs[LEDIdx];
|
led LED = Assembly->LEDs[LEDIdx];
|
||||||
TestAssembly.Colors[LED.Index].R = 255;
|
Assembly->Colors[LED.Index].R = 255;
|
||||||
TestAssembly.Colors[LED.Index].B = 255;
|
Assembly->Colors[LED.Index].B = 255;
|
||||||
TestAssembly.Colors[LED.Index].G = 255;
|
Assembly->Colors[LED.Index].G = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
TestPatternTwo(app_state* State, r32 Time)
|
TestPatternTwo(assembly* Assembly, r32 Time)
|
||||||
{
|
{
|
||||||
if (Time > 2 * PI * 100) { Time = 0; }
|
r32 PeriodicTime = (Time / PI) * 2;
|
||||||
r32 SinAdjusted = 0.5f + (GSSin(Time * 0.01f) * .5f);
|
|
||||||
u8 Brightness = (u8)(GSClamp01(SinAdjusted) * 255);
|
|
||||||
|
|
||||||
array_entry_handle TestAssemblyHandle = *GetElementAtIndex(0, State->ActiveAssemblyIndecies);
|
r32 ZeroOneSin = (GSSin(PeriodicTime) * .5f) + .5f;
|
||||||
assembly TestAssembly = *GetElementWithHandle(TestAssemblyHandle, State->AssemblyList);
|
r32 ZeroOneCos = (GSCos(PeriodicTime) * .5f) + .5f;
|
||||||
for (s32 Range = 0; Range < TestAssembly.LEDUniverseMapCount; Range++)
|
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
||||||
|
|
||||||
|
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];
|
leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range];
|
||||||
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
||||||
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
||||||
LEDIdx++)
|
LEDIdx++)
|
||||||
{
|
{
|
||||||
led LED = TestAssembly.LEDs[LEDIdx];
|
led LED = Assembly->LEDs[LEDIdx];
|
||||||
TestAssembly.Colors[LED.Index].R = Brightness;
|
|
||||||
TestAssembly.Colors[LED.Index].B = 0;
|
v4 Position = LED.Position;
|
||||||
TestAssembly.Colors[LED.Index].G = Brightness;
|
|
||||||
|
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
|
internal void
|
||||||
TestPatternThree(app_state* State, r32 Time)
|
TestPatternThree(assembly* Assembly, r32 Time)
|
||||||
{
|
{
|
||||||
r32 GreenSize = 20.0f;
|
r32 GreenSize = 20.0f;
|
||||||
r32 BlueSize = 25.0f;
|
r32 BlueSize = 25.0f;
|
||||||
|
@ -128,16 +162,14 @@ r32 GreenSize = 20.0f;
|
||||||
r32 BluePosition = -BlueSize + (Time * 25);
|
r32 BluePosition = -BlueSize + (Time * 25);
|
||||||
r32 RedPosition = (100 + RedSize) + (Time * -35);
|
r32 RedPosition = (100 + RedSize) + (Time * -35);
|
||||||
|
|
||||||
array_entry_handle TestAssemblyHandle = *GetElementAtIndex(0, State->ActiveAssemblyIndecies);
|
for (s32 Range = 0; Range < Assembly->LEDUniverseMapCount; Range++)
|
||||||
assembly TestAssembly = *GetElementWithHandle(TestAssemblyHandle, State->AssemblyList);
|
|
||||||
for (s32 Range = 0; Range < TestAssembly.LEDUniverseMapCount; Range++)
|
|
||||||
{
|
{
|
||||||
leds_in_universe_range LEDUniverseRange = TestAssembly.LEDUniverseMap[Range];
|
leds_in_universe_range LEDUniverseRange = Assembly->LEDUniverseMap[Range];
|
||||||
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
for (s32 LEDIdx = LEDUniverseRange.RangeStart;
|
||||||
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
LEDIdx < LEDUniverseRange.RangeOnePastLast;
|
||||||
LEDIdx++)
|
LEDIdx++)
|
||||||
{
|
{
|
||||||
led LED = TestAssembly.LEDs[LEDIdx];
|
led LED = Assembly->LEDs[LEDIdx];
|
||||||
u8 Red = 0;
|
u8 Red = 0;
|
||||||
u8 Green = 0;
|
u8 Green = 0;
|
||||||
u8 Blue = 0;
|
u8 Blue = 0;
|
||||||
|
@ -154,9 +186,9 @@ r32 GreenSize = 20.0f;
|
||||||
r32 RedBrightness = GSClamp(0.0f, RedSize - RedDistance, RedSize) / RedSize;
|
r32 RedBrightness = GSClamp(0.0f, RedSize - RedDistance, RedSize) / RedSize;
|
||||||
Red = (u8)(RedBrightness * 255);
|
Red = (u8)(RedBrightness * 255);
|
||||||
|
|
||||||
TestAssembly.Colors[LED.Index].R = Red;
|
Assembly->Colors[LED.Index].R = Red;
|
||||||
TestAssembly.Colors[LED.Index].B = Blue;
|
Assembly->Colors[LED.Index].B = Blue;
|
||||||
TestAssembly.Colors[LED.Index].G = Green;
|
Assembly->Colors[LED.Index].G = Green;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ GetAssemblyMemorySizeFromDefinition(assembly_definition Definition, string Name)
|
||||||
internal assembly
|
internal assembly
|
||||||
ConstructAssemblyFromDefinition (assembly_definition Definition,
|
ConstructAssemblyFromDefinition (assembly_definition Definition,
|
||||||
string AssemblyName,
|
string AssemblyName,
|
||||||
v3 RootPosition,
|
v4 RootPosition,
|
||||||
r32 Scale,
|
r32 Scale,
|
||||||
memory_arena Arena)
|
memory_arena Arena)
|
||||||
{
|
{
|
||||||
|
@ -43,8 +43,8 @@ ConstructAssemblyFromDefinition (assembly_definition Definition,
|
||||||
// now. The assert is to remind you to create more cases when necessary
|
// now. The assert is to remind you to create more cases when necessary
|
||||||
Assert(StripDef.InterpolationType == StripInterpolate_Points);
|
Assert(StripDef.InterpolationType == StripInterpolate_Points);
|
||||||
|
|
||||||
v4 WS_StripStart = V4(StripDef.InterpolatePositionStart * Scale, 1);
|
v4 WS_StripStart = RootPosition + V4(StripDef.InterpolatePositionStart * Scale, 1);
|
||||||
v4 WS_StripEnd = V4(StripDef.InterpolatePositionEnd * Scale, 1);
|
v4 WS_StripEnd = RootPosition + V4(StripDef.InterpolatePositionEnd * Scale, 1);
|
||||||
s32 LEDsInStripCount = StripDef.LEDsPerStrip;
|
s32 LEDsInStripCount = StripDef.LEDsPerStrip;
|
||||||
|
|
||||||
Assert(Assembly.LEDCount + LEDsInStripCount <= Definition.TotalLEDCount);
|
Assert(Assembly.LEDCount + LEDsInStripCount <= Definition.TotalLEDCount);
|
||||||
|
@ -63,6 +63,9 @@ ConstructAssemblyFromDefinition (assembly_definition Definition,
|
||||||
return Assembly;
|
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
|
internal void
|
||||||
LoadAssembly (app_state* State, context Context, char* Path)
|
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.Alloc = (gs_memory_alloc*)Context.PlatformAlloc;
|
||||||
AssemblyArena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
|
AssemblyArena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
|
||||||
|
|
||||||
|
v4 Offset = TempAssemblyOffsets[State->ActiveAssemblyIndecies.Used % TempAssemblyOffsetsCount];
|
||||||
assembly NewAssembly = ConstructAssemblyFromDefinition(AssemblyDefinition,
|
assembly NewAssembly = ConstructAssemblyFromDefinition(AssemblyDefinition,
|
||||||
FileName,
|
FileName,
|
||||||
v3{0, 0, 0},
|
Offset,
|
||||||
Scale,
|
Scale,
|
||||||
AssemblyArena);
|
AssemblyArena);
|
||||||
array_entry_handle NewAssemblyHandle = PushElement(NewAssembly, &State->AssemblyList);
|
array_entry_handle NewAssemblyHandle = PushElement(NewAssembly, &State->AssemblyList);
|
||||||
|
|
|
@ -147,7 +147,6 @@ RemoveElementAtIndex (s32 Index, element_type##_array* Buffer) \
|
||||||
Entry->Free.Next = Buffer->FreeList.Next; \
|
Entry->Free.Next = Buffer->FreeList.Next; \
|
||||||
Buffer->FreeList.Next = &Entry->Free; \
|
Buffer->FreeList.Next = &Entry->Free; \
|
||||||
\
|
\
|
||||||
--Buffer->Used; \
|
|
||||||
} \
|
} \
|
||||||
|
|
||||||
// END OF CRAZY MACRO
|
// END OF CRAZY MACRO
|
||||||
|
@ -184,8 +183,12 @@ GrowBuffer(element_type##_contiguous_array* Buffer) \
|
||||||
internal element_type* \
|
internal element_type* \
|
||||||
GetElementAtIndex (s32 Index, element_type##_contiguous_array Buffer) \
|
GetElementAtIndex (s32 Index, element_type##_contiguous_array Buffer) \
|
||||||
{ \
|
{ \
|
||||||
|
element_type* Entry = 0; \
|
||||||
|
if (Index <= Buffer.Used) \
|
||||||
|
{ \
|
||||||
bucket_index BucketIndex = GetBucketIndexForIndex(Index, Buffer.BucketSize); \
|
bucket_index BucketIndex = GetBucketIndexForIndex(Index, Buffer.BucketSize); \
|
||||||
element_type* Entry = Buffer.Buckets[BucketIndex.Bucket] + BucketIndex.IndexInBucket; \
|
Entry = Buffer.Buckets[BucketIndex.Bucket] + BucketIndex.IndexInBucket; \
|
||||||
|
} \
|
||||||
return Entry; \
|
return Entry; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
|
|
@ -17,6 +17,74 @@ PANEL_CLEANUP_PROC(AnimationTimeline_Cleanup)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
DrawFrameBar (animation_system* AnimationSystem, render_command_buffer* RenderBuffer, s32 StartFrame, s32 EndFrame, v2 PanelMin, v2 PanelMax, interface_config Interface, mouse_state Mouse)
|
||||||
|
{
|
||||||
|
MakeStringBuffer(TempString, 256);
|
||||||
|
|
||||||
|
s32 FrameCount = EndFrame - StartFrame;
|
||||||
|
|
||||||
|
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
|
||||||
|
if (MouseButtonHeldDown(Mouse.LeftButtonState)
|
||||||
|
&& PointIsInRange(Mouse.DownPos, FrameBarMin, FrameBarMax))
|
||||||
|
{
|
||||||
|
r32 MouseX = Mouse.DownPos.x;
|
||||||
|
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;
|
||||||
|
PrintF(&TempString, "%d", Frame);
|
||||||
|
|
||||||
|
r32 FramePercent = (r32)f / (r32)FrameCount;
|
||||||
|
r32 FrameX = GSLerp(PanelMin.x, PanelMax.x, FramePercent);
|
||||||
|
v2 FrameTextPos = v2{FrameX, FrameBarMin.y + 2};
|
||||||
|
DrawString(RenderBuffer, TempString, Interface.Font, FrameTextPos, WhiteV4);
|
||||||
|
|
||||||
|
// Frame Vertical Slices
|
||||||
|
v2 LineTop = v2{FrameX, FrameBarMin.y};
|
||||||
|
v2 LineBottom = v2{FrameX + 1, PanelMin.y};
|
||||||
|
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
|
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)
|
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)
|
||||||
{
|
{
|
||||||
|
@ -27,44 +95,26 @@ s32 FrameCount = EndFrame - StartFrame;
|
||||||
|
|
||||||
r32 AnimationPanelHeight = PanelMax.y - PanelMin.y;
|
r32 AnimationPanelHeight = PanelMax.y - PanelMin.y;
|
||||||
r32 AnimationPanelWidth = PanelMax.x - PanelMin.x;
|
r32 AnimationPanelWidth = PanelMax.x - PanelMin.x;
|
||||||
PushRenderQuad2D(RenderBuffer, PanelMin, PanelMax, v4{.22f, .22f, .22f, 1.f});
|
|
||||||
|
|
||||||
// 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
|
|
||||||
if (MouseButtonHeldDown(Mouse.LeftButtonState)
|
|
||||||
&& PointIsInRange(Mouse.DownPos, FrameBarMin, FrameBarMax))
|
|
||||||
{
|
{
|
||||||
r32 MouseX = Mouse.DownPos.x;
|
s32 FirstPlayableFrame = (AnimationSystem->AnimationStart / AnimationSystem->SecondsPerFrame);
|
||||||
r32 MousePercentX = (MouseX - FrameBarMin.x) / (FrameBarMax.x - FrameBarMin.y);
|
s32 LastPlayableFrame = (AnimationSystem->AnimationEnd / AnimationSystem->SecondsPerFrame);
|
||||||
s32 MouseFrame = (s32)((MousePercentX * FrameCount) + StartFrame);
|
|
||||||
r32 MouseFrameTime = (r32)MouseFrame * AnimationSystem->SecondsPerFrame;
|
r32 FirstPlayablePercentX = ((r32)(FirstPlayableFrame - StartFrame) / (r32)FrameCount);
|
||||||
AnimationSystem->Time = MouseFrameTime;
|
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});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 f = 0; f < FrameCount; f += 10)
|
r32 FrameBarBottom = DrawFrameBar(AnimationSystem, RenderBuffer, StartFrame, EndFrame, PanelMin, PanelMax, State->Interface, Mouse);
|
||||||
{
|
|
||||||
s32 Frame = StartFrame + f;
|
|
||||||
PrintF(&TempString, "%d", Frame);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Frame Vertical Slices
|
|
||||||
v2 LineTop = v2{FrameX, FrameBarMin.y};
|
|
||||||
v2 LineBottom = v2{FrameX + 1, PanelMin.y};
|
|
||||||
PushRenderQuad2D(RenderBuffer, LineTop, LineBottom, v4{.16f, .16f, .16f, 1.f});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animation Blocks
|
// Animation Blocks
|
||||||
v2 TimelineMin = PanelMin;
|
v2 TimelineMin = PanelMin;
|
||||||
v2 TimelineMax = v2{PanelMax.x, FrameBarMin.y};
|
v2 TimelineMax = v2{PanelMax.x, FrameBarBottom};
|
||||||
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState);
|
b32 MouseDownAndNotHandled = MouseButtonTransitionedDown(Mouse.LeftButtonState);
|
||||||
for (u32 i = 0; i < AnimationSystem->BlocksCount; i++)
|
for (u32 i = 0; i < AnimationSystem->BlocksCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -77,27 +127,15 @@ for (u32 i = 0; i < AnimationSystem->BlocksCount; i++)
|
||||||
|
|
||||||
animation_block AnimationBlockAt = AnimationBlockEntry.Block;
|
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;
|
v4 BlockColor = BlackV4;
|
||||||
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle))
|
||||||
{
|
{
|
||||||
BlockColor = PinkV4;
|
BlockColor = PinkV4;
|
||||||
}
|
}
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, Min, Max, BlockColor);
|
rect BlockBounds = DrawAnimationBlock(AnimationBlockAt, BlockColor, AnimationSystem->SecondsPerFrame, FrameCount, StartFrame, TimelineMin, TimelineMax, RenderBuffer);
|
||||||
PushRenderBoundingBox2D(RenderBuffer, Min, Max, 1, WhiteV4);
|
|
||||||
|
|
||||||
if (PointIsInRange(Mouse.Pos, Min, Max)
|
if (PointIsInRange(Mouse.Pos, BlockBounds.Min, BlockBounds.Max)
|
||||||
&& MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
&& MouseButtonTransitionedDown(Mouse.LeftButtonState))
|
||||||
{
|
{
|
||||||
MouseDownAndNotHandled = false;
|
MouseDownAndNotHandled = false;
|
||||||
|
@ -115,7 +153,7 @@ for (u32 i = 0; i < AnimationSystem->BlocksCount; i++)
|
||||||
|
|
||||||
// Time Slider
|
// Time Slider
|
||||||
s32 SliderFrame = AnimationSystem->Time / AnimationSystem->SecondsPerFrame;
|
s32 SliderFrame = AnimationSystem->Time / AnimationSystem->SecondsPerFrame;
|
||||||
r32 TimePercent = (r32)SliderFrame / (r32)EndFrame;
|
r32 TimePercent = (r32)(SliderFrame - StartFrame) / (r32)FrameCount;
|
||||||
r32 SliderX = PanelMin.x + (AnimationPanelWidth * TimePercent);
|
r32 SliderX = PanelMin.x + (AnimationPanelWidth * TimePercent);
|
||||||
v2 SliderMin = v2{SliderX, PanelMin.y};
|
v2 SliderMin = v2{SliderX, PanelMin.y};
|
||||||
v2 SliderMax = v2{SliderX + 1, PanelMax.y - 25};
|
v2 SliderMax = v2{SliderX + 1, PanelMax.y - 25};
|
||||||
|
@ -125,7 +163,7 @@ s32 SliderFrame = AnimationSystem->Time / AnimationSystem->SecondsPerFrame;
|
||||||
|
|
||||||
r32 SliderHalfWidth = 10;
|
r32 SliderHalfWidth = 10;
|
||||||
v2 HeadMin = v2{SliderX - SliderHalfWidth, SliderMax.y};
|
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);
|
PushRenderQuad2D(RenderBuffer, HeadMin, HeadMax, TimeSliderColor);
|
||||||
|
|
||||||
PrintF(&TempString, "%d", SliderFrame);
|
PrintF(&TempString, "%d", SliderFrame);
|
||||||
|
@ -158,9 +196,10 @@ PANEL_RENDER_PROC(AnimationTimeline_Render)
|
||||||
v2 TimelineMax = v2{PanelMax.x, PanelMax.y - OptionsRowHeight};
|
v2 TimelineMax = v2{PanelMax.x, PanelMax.y - OptionsRowHeight};
|
||||||
if (TimelineMax.y - TimelineMin.y > 0)
|
if (TimelineMax.y - TimelineMin.y > 0)
|
||||||
{
|
{
|
||||||
|
s32 FrameStart = (s32)(State->AnimationSystem.AnimationStart / State->AnimationSystem.SecondsPerFrame);
|
||||||
s32 FrameEnd = (s32)(State->AnimationSystem.AnimationEnd / State->AnimationSystem.SecondsPerFrame);
|
s32 FrameEnd = (s32)(State->AnimationSystem.AnimationEnd / State->AnimationSystem.SecondsPerFrame);
|
||||||
SelectedBlockHandle = DrawAnimationTimeline(&State->AnimationSystem,
|
SelectedBlockHandle = DrawAnimationTimeline(&State->AnimationSystem,
|
||||||
0, FrameEnd,
|
FrameStart - 20, FrameEnd + 20,
|
||||||
TimelineMin, TimelineMax,
|
TimelineMin, TimelineMax,
|
||||||
SelectedBlockHandle,
|
SelectedBlockHandle,
|
||||||
RenderBuffer, State, Mouse);
|
RenderBuffer, State, Mouse);
|
||||||
|
|
|
@ -51,7 +51,7 @@ array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyI
|
||||||
if (MouseButtonTransitionedUp(Mouse.LeftButtonState)
|
if (MouseButtonTransitionedUp(Mouse.LeftButtonState)
|
||||||
&& PointIsInRange(Mouse.Pos, XLowerLeft, LineMax))
|
&& PointIsInRange(Mouse.Pos, XLowerLeft, LineMax))
|
||||||
{
|
{
|
||||||
UnloadAssembly(i, State, Context);
|
UnloadAssembly(AssemblyHandle.Index, State, Context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i == State->ActiveAssemblyIndecies.Used)
|
else if (i == State->ActiveAssemblyIndecies.Used)
|
||||||
|
|
Loading…
Reference in New Issue