Added rudimentary layers to the animation system.
This commit is contained in:
parent
3a20883a49
commit
de1a9474f0
|
@ -298,7 +298,7 @@ int main(int ArgCount, char* Args[])
|
|||
string_builder PanelCodeGen = {0};
|
||||
GeneratePanelMetaInfo(Meta, &PanelCodeGen);
|
||||
|
||||
string TypeInfoHFilePath = AllocAndConcatStrings(GeneratedFilesDirectory, MakeStringLiteral("gs_meta_genreated_typeinfo.h"));
|
||||
string TypeInfoHFilePath = AllocAndConcatStrings(GeneratedFilesDirectory, MakeStringLiteral("gs_meta_generated_typeinfo.h"));
|
||||
FILE* TypeInfoH = fopen(TypeInfoHFilePath.Memory, "w");
|
||||
if (TypeInfoH)
|
||||
{
|
||||
|
@ -315,7 +315,7 @@ int main(int ArgCount, char* Args[])
|
|||
}
|
||||
|
||||
string NodeInfoHFilePath = AllocAndConcatStrings(GeneratedFilesDirectory, MakeStringLiteral("foldhaus_nodes_generated.h"));
|
||||
FILE* NodeInfoH = fopen(TypeInfoHFilePath.Memory, "w");
|
||||
FILE* NodeInfoH = fopen(NodeInfoHFilePath.Memory, "w");
|
||||
if (NodeInfoH)
|
||||
{
|
||||
WriteStringBuilderToFile(*NodeTypeGen.Builder, NodeInfoH);
|
||||
|
|
|
@ -10,8 +10,8 @@ typedef ANIMATION_PROC(animation_proc);
|
|||
|
||||
struct frame_range
|
||||
{
|
||||
u32 Min;
|
||||
u32 Max;
|
||||
s32 Min;
|
||||
s32 Max;
|
||||
};
|
||||
|
||||
struct animation_block
|
||||
|
@ -21,19 +21,28 @@ struct animation_block
|
|||
u32 Layer;
|
||||
};
|
||||
|
||||
struct anim_layer
|
||||
{
|
||||
string Name;
|
||||
};
|
||||
|
||||
#define ANIMATION_SYSTEM_LAYERS_MAX 128
|
||||
#define ANIMATION_SYSTEM_BLOCKS_MAX 128
|
||||
struct animation_system
|
||||
{
|
||||
memory_arena Storage;
|
||||
|
||||
gs_list<animation_block> Blocks;
|
||||
anim_layer* Layers;
|
||||
u32 LayersCount;
|
||||
u32 LayersMax;
|
||||
|
||||
// NOTE(Peter): The frame currently being displayed/processed. you
|
||||
// can see which frame you're on by looking at the time slider on the timeline
|
||||
// panel
|
||||
u32 CurrentFrame;
|
||||
u32 LastUpdatedFrame;
|
||||
s32 CurrentFrame;
|
||||
s32 LastUpdatedFrame;
|
||||
r32 SecondsPerFrame;
|
||||
|
||||
b32 TimelineShouldAdvance;
|
||||
|
||||
// Timeline
|
||||
|
@ -48,7 +57,7 @@ SecondsToFrames(r32 Seconds, animation_system System)
|
|||
}
|
||||
|
||||
inline b32
|
||||
FrameIsInRange(u32 Frame, frame_range Range)
|
||||
FrameIsInRange(s32 Frame, frame_range Range)
|
||||
{
|
||||
b32 Result = (Frame >= Range.Min) && (Frame <= Range.Max);
|
||||
return Result;
|
||||
|
@ -57,7 +66,7 @@ FrameIsInRange(u32 Frame, frame_range Range)
|
|||
internal u32
|
||||
GetFrameCount(frame_range Range)
|
||||
{
|
||||
u32 Result = Range.Max - Range.Min;
|
||||
u32 Result = (u32)GSMax(0, Range.Max - Range.Min);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -69,17 +78,17 @@ FrameToPercentRange(s32 Frame, frame_range Range)
|
|||
return Result;
|
||||
}
|
||||
|
||||
internal u32
|
||||
internal s32
|
||||
PercentToFrameInRange(r32 Percent, frame_range Range)
|
||||
{
|
||||
u32 Result = Range.Min + (u32)(Percent * GetFrameCount(Range));
|
||||
s32 Result = Range.Min + (s32)(Percent * GetFrameCount(Range));
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal u32
|
||||
ClampFrameToRange(u32 Frame, frame_range Range)
|
||||
internal s32
|
||||
ClampFrameToRange(s32 Frame, frame_range Range)
|
||||
{
|
||||
u32 Result = Frame;
|
||||
s32 Result = Frame;
|
||||
if (Result < Range.Min)
|
||||
{
|
||||
Result = Range.Min;
|
||||
|
@ -91,5 +100,69 @@ ClampFrameToRange(u32 Frame, frame_range Range)
|
|||
return Result;
|
||||
}
|
||||
|
||||
// Blocks
|
||||
|
||||
internal gs_list_handle
|
||||
AddAnimationBlock(u32 StartFrame, s32 EndFrame, u32 AnimationProcHandle, u32 Layer, animation_system* AnimationSystem)
|
||||
{
|
||||
gs_list_handle Result = {0};
|
||||
animation_block NewBlock = {0};
|
||||
NewBlock.Range.Min = StartFrame;
|
||||
NewBlock.Range.Max = EndFrame;
|
||||
NewBlock.AnimationProcHandle = AnimationProcHandle;
|
||||
NewBlock.Layer = Layer;
|
||||
Result = AnimationSystem->Blocks.PushElementOnList(NewBlock);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
RemoveAnimationBlock(gs_list_handle AnimationBlockHandle, animation_system* AnimationSystem)
|
||||
{
|
||||
Assert(ListHandleIsValid(AnimationBlockHandle));
|
||||
AnimationSystem->Blocks.FreeElementWithHandle(AnimationBlockHandle);
|
||||
}
|
||||
|
||||
// Layers
|
||||
internal u32
|
||||
AddLayer (string Name, animation_system* AnimationSystem)
|
||||
{
|
||||
// TODO(Peter): If this assert fires its time to make the layer buffer system
|
||||
// resizable.
|
||||
Assert(AnimationSystem->LayersCount < AnimationSystem->LayersMax);
|
||||
|
||||
u32 Result = 0;
|
||||
Result = AnimationSystem->LayersCount++;
|
||||
anim_layer* NewLayer = AnimationSystem->Layers + Result;
|
||||
*NewLayer = {0};
|
||||
NewLayer->Name = MakeString(PushArray(&AnimationSystem->Storage, char, Name.Length), Name.Length);
|
||||
CopyStringTo(Name, &NewLayer->Name);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
RemoveLayer (u32 LayerIndex, animation_system* AnimationSystem)
|
||||
{
|
||||
Assert(LayerIndex < AnimationSystem->LayersMax);
|
||||
Assert(LayerIndex < AnimationSystem->LayersCount);
|
||||
for (u32 i = LayerIndex; i < AnimationSystem->LayersCount - 1; i++)
|
||||
{
|
||||
AnimationSystem->Layers[i] = AnimationSystem->Layers[i + 1];
|
||||
}
|
||||
for (u32 i = AnimationSystem->Blocks.Used -= 1; i >= 0; i--)
|
||||
{
|
||||
gs_list_entry<animation_block>* Entry = AnimationSystem->Blocks.GetEntryAtIndex(i);
|
||||
if (EntryIsFree(Entry)) { continue; }
|
||||
animation_block* Block = &Entry->Value;
|
||||
if (Block->Layer > LayerIndex)
|
||||
{
|
||||
Block->Layer -= 1;
|
||||
}
|
||||
else if (Block->Layer == LayerIndex)
|
||||
{
|
||||
AnimationSystem->Blocks.FreeElementAtIndex(i);
|
||||
}
|
||||
}
|
||||
AnimationSystem->LayersCount -= 1;
|
||||
}
|
||||
#define FOLDHAUS_ANIMATION
|
||||
#endif // FOLDHAUS_ANIMATION
|
|
@ -190,6 +190,11 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
|||
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
|
||||
State->AnimationSystem.PlayableRange.Min = 0;
|
||||
State->AnimationSystem.PlayableRange.Max = SecondsToFrames(15, State->AnimationSystem);
|
||||
State->AnimationSystem.LayersMax = 32;
|
||||
State->AnimationSystem.Layers = PushArray(&State->Permanent, anim_layer, State->AnimationSystem.LayersMax);
|
||||
AddLayer(MakeStringLiteral("Base Layer"), &State->AnimationSystem);
|
||||
AddLayer(MakeStringLiteral("Color Layer"), &State->AnimationSystem);
|
||||
AddLayer(MakeStringLiteral("Sparkles"), &State->AnimationSystem);
|
||||
} // End Animation Playground
|
||||
|
||||
|
||||
|
@ -330,7 +335,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
}
|
||||
}
|
||||
|
||||
u32 CurrentFrame = State->AnimationSystem.CurrentFrame;
|
||||
s32 CurrentFrame = State->AnimationSystem.CurrentFrame;
|
||||
if (CurrentFrame != State->AnimationSystem.LastUpdatedFrame)
|
||||
{
|
||||
State->AnimationSystem.LastUpdatedFrame = CurrentFrame;
|
||||
|
@ -339,40 +344,37 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
|||
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
|
||||
{
|
||||
gs_list_entry<animation_block>* BlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i);
|
||||
if (!EntryIsFree(BlockEntry))
|
||||
if (EntryIsFree(BlockEntry)) { continue; }
|
||||
animation_block Block = BlockEntry->Value;
|
||||
if (CurrentFrame < Block.Range.Min || CurrentFrame > Block.Range.Max) { continue; }
|
||||
|
||||
for (u32 j = 0; j < State->ActiveAssemblyIndecies.Used; j++)
|
||||
{
|
||||
animation_block Block = BlockEntry->Value;
|
||||
if (CurrentFrame >= Block.Range.Min && CurrentFrame <= Block.Range.Max)
|
||||
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(j);
|
||||
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle);
|
||||
|
||||
u32 FramesIntoBlock = CurrentFrame - Block.Range.Min;
|
||||
r32 SecondsIntoBlock = FramesIntoBlock * State->AnimationSystem.SecondsPerFrame;
|
||||
// TODO(Peter): Temporary
|
||||
switch(Block.AnimationProcHandle)
|
||||
{
|
||||
for (u32 j = 0; j < State->ActiveAssemblyIndecies.Used; j++)
|
||||
case 1:
|
||||
{
|
||||
gs_list_handle AssemblyHandle = *State->ActiveAssemblyIndecies.GetElementAtIndex(j);
|
||||
assembly* Assembly = State->AssemblyList.GetElementWithHandle(AssemblyHandle);
|
||||
|
||||
u32 FramesIntoBlock = CurrentFrame - Block.Range.Min;
|
||||
r32 SecondsIntoBlock = FramesIntoBlock * State->AnimationSystem.SecondsPerFrame;
|
||||
// TODO(Peter): Temporary
|
||||
switch(Block.AnimationProcHandle)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
TestPatternOne(Assembly, SecondsIntoBlock);
|
||||
}break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
TestPatternTwo(Assembly, SecondsIntoBlock);
|
||||
}break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
TestPatternThree(Assembly, SecondsIntoBlock);
|
||||
}break;
|
||||
|
||||
// NOTE(Peter): Zero is invalid
|
||||
InvalidDefaultCase;
|
||||
}
|
||||
}
|
||||
TestPatternOne(Assembly, SecondsIntoBlock);
|
||||
}break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
TestPatternTwo(Assembly, SecondsIntoBlock);
|
||||
}break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
TestPatternThree(Assembly, SecondsIntoBlock);
|
||||
}break;
|
||||
|
||||
// NOTE(Peter): Zero is invalid
|
||||
InvalidDefaultCase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ struct app_state
|
|||
|
||||
animation_system AnimationSystem;
|
||||
gs_list_handle SelectedAnimationBlockHandle;
|
||||
u32 SelectedAnimationLayer;
|
||||
|
||||
panel_system PanelSystem;
|
||||
panel* HotPanel;
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
enum node_type
|
||||
{
|
||||
NodeType_Count,
|
||||
};
|
||||
|
||||
node_specification NodeSpecifications[] = {
|
||||
};
|
||||
s32 NodeSpecificationsCount = 0;
|
||||
|
||||
internal void CallNodeProc(u32 SpecificationIndex, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime)
|
||||
{
|
||||
node_specification Spec = NodeSpecifications[SpecificationIndex];
|
||||
switch (Spec.Type)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
enum node_type
|
||||
{
|
||||
NodeType_RevolvingDiscs,
|
||||
NodeType_SolidColorProc,
|
||||
NodeType_VerticalColorFadeProc,
|
||||
NodeType_Count,
|
||||
};
|
||||
|
||||
static node_specification_ NodeSpecifications[] = {
|
||||
{ NodeType_RevolvingDiscs, {"RevolvingDiscs", 14}, gsm_StructType_revolving_discs_data },
|
||||
{ NodeType_SolidColorProc, {"SolidColorProc", 14}, gsm_StructType_solid_color_data },
|
||||
{ NodeType_VerticalColorFadeProc, {"VerticalColorFadeProc", 21}, gsm_StructType_vertical_color_fade_data },
|
||||
};
|
||||
|
||||
void CallNodeProc(node_type Type, u8* NodeData)
|
||||
{
|
||||
switch(Type) {
|
||||
case NodeType_RevolvingDiscs:
|
||||
{
|
||||
RevolvingDiscs((revolving_discs_data*)NodeData);
|
||||
} break;
|
||||
case NodeType_SolidColorProc:
|
||||
{
|
||||
SolidColorProc((solid_color_data*)NodeData);
|
||||
} break;
|
||||
case NodeType_VerticalColorFadeProc:
|
||||
{
|
||||
VerticalColorFadeProc((vertical_color_fade_data*)NodeData);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
|
@ -32,33 +32,14 @@ GetXPositionFromFrameInAnimationPanel (u32 Frame, rect PanelBounds, frame_range
|
|||
}
|
||||
|
||||
internal gs_list_handle
|
||||
AddAnimationBlock(u32 StartFrame, u32 EndFrame, u32 AnimationProcHandle, animation_system* AnimationSystem)
|
||||
{
|
||||
gs_list_handle Result = {0};
|
||||
animation_block NewBlock = {0};
|
||||
NewBlock.Range.Min = StartFrame;
|
||||
NewBlock.Range.Max = EndFrame;
|
||||
NewBlock.AnimationProcHandle = AnimationProcHandle;
|
||||
Result = AnimationSystem->Blocks.PushElementOnList(NewBlock);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal gs_list_handle
|
||||
AddAnimationBlockAtCurrentTime (u32 AnimationProcHandle, animation_system* System)
|
||||
AddAnimationBlockAtCurrentTime (u32 AnimationProcHandle, u32 Layer, animation_system* System)
|
||||
{
|
||||
u32 NewBlockStart = System->CurrentFrame;
|
||||
u32 NewBlockEnd = NewBlockStart + SecondsToFrames(3, *System);
|
||||
gs_list_handle Result = AddAnimationBlock(NewBlockStart, NewBlockEnd, AnimationProcHandle, System);
|
||||
gs_list_handle Result = AddAnimationBlock(NewBlockStart, NewBlockEnd, AnimationProcHandle, Layer, System);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
DeleteAnimationBlock(gs_list_handle AnimationBlockHandle, app_state* State)
|
||||
{
|
||||
State->AnimationSystem.Blocks.FreeElementWithHandle(AnimationBlockHandle);
|
||||
State->SelectedAnimationBlockHandle = {0};
|
||||
}
|
||||
|
||||
internal void
|
||||
SelectAnimationBlock(gs_list_handle BlockHandle, app_state* State)
|
||||
{
|
||||
|
@ -75,7 +56,8 @@ FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand)
|
|||
{
|
||||
if(ListHandleIsValid(State->SelectedAnimationBlockHandle))
|
||||
{
|
||||
DeleteAnimationBlock(State->SelectedAnimationBlockHandle, State);
|
||||
RemoveAnimationBlock(State->SelectedAnimationBlockHandle, &State->AnimationSystem);
|
||||
State->SelectedAnimationBlockHandle = {0};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +75,7 @@ OPERATION_STATE_DEF(drag_time_marker_operation_state)
|
|||
OPERATION_RENDER_PROC(UpdateDragTimeMarker)
|
||||
{
|
||||
drag_time_marker_operation_state* OpState = (drag_time_marker_operation_state*)Operation.OpStateMemory;
|
||||
frame_range Range = { (u32)OpState->StartFrame, (u32)OpState->EndFrame };
|
||||
frame_range Range = { OpState->StartFrame, OpState->EndFrame };
|
||||
u32 FrameAtMouseX = GetFrameFromPointInAnimationPanel(Mouse.Pos, OpState->TimelineBounds, Range);
|
||||
State->AnimationSystem.CurrentFrame = FrameAtMouseX;
|
||||
}
|
||||
|
@ -174,13 +156,13 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
|||
|
||||
if (GSAbs(Mouse.DownPos.x - ClipInitialStartFrameXPosition) < CLICK_ANIMATION_BLOCK_EDGE_MAX_SCREEN_DISTANCE)
|
||||
{
|
||||
u32 NewStartFrame = OpState->ClipRange.Min + FrameOffset;
|
||||
s32 NewStartFrame = OpState->ClipRange.Min + FrameOffset;
|
||||
if (FrameOffset < 0)
|
||||
{
|
||||
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
|
||||
{
|
||||
gs_list_entry<animation_block>* OtherBlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i);
|
||||
if (OtherBlockEntry->Free.NextFreeEntry != 0) { continue; }
|
||||
if (EntryIsFree(OtherBlockEntry)) { continue; }
|
||||
animation_block OtherBlock = OtherBlockEntry->Value;
|
||||
NewStartFrame = AttemptToSnapPosition(NewStartFrame, OtherBlock.Range.Max);
|
||||
}
|
||||
|
@ -202,7 +184,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
|||
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
|
||||
{
|
||||
gs_list_entry<animation_block>* OtherBlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i);
|
||||
if (OtherBlockEntry->Free.NextFreeEntry != 0) { continue; }
|
||||
if (EntryIsFree(OtherBlockEntry)) { continue; }
|
||||
animation_block OtherBlock = OtherBlockEntry->Value;
|
||||
NewEndFrame = AttemptToSnapPosition(NewEndFrame, OtherBlock.Range.Min);
|
||||
}
|
||||
|
@ -223,7 +205,7 @@ OPERATION_RENDER_PROC(UpdateDragAnimationClip)
|
|||
for (u32 i = 0; i < State->AnimationSystem.Blocks.Used; i++)
|
||||
{
|
||||
gs_list_entry<animation_block>* OtherBlockEntry = State->AnimationSystem.Blocks.GetEntryAtIndex(i);
|
||||
if (OtherBlockEntry->Free.NextFreeEntry != 0) { continue; }
|
||||
if (EntryIsFree(OtherBlockEntry)) { continue; }
|
||||
animation_block OtherBlock = OtherBlockEntry->Value;
|
||||
|
||||
u32 SnapFramesAmount = 0;
|
||||
|
@ -277,7 +259,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(AddAnimationBlockCommand)
|
|||
panel_and_bounds ActivePanel = GetPanelContainingPoint(Mouse.Pos, &State->PanelSystem, State->WindowBounds);
|
||||
frame_range Range = State->AnimationSystem.PlayableRange;
|
||||
u32 MouseDownFrame = GetFrameFromPointInAnimationPanel(Mouse.Pos, ActivePanel.Bounds, Range);
|
||||
gs_list_handle NewBlockHandle = AddAnimationBlock(MouseDownFrame, MouseDownFrame + SecondsToFrames(3, State->AnimationSystem), 4, &State->AnimationSystem);
|
||||
gs_list_handle NewBlockHandle = AddAnimationBlock(MouseDownFrame, MouseDownFrame + SecondsToFrames(3, State->AnimationSystem), 4, State->SelectedAnimationLayer, &State->AnimationSystem);
|
||||
SelectAnimationBlock(NewBlockHandle, State);
|
||||
}
|
||||
|
||||
|
@ -370,12 +352,10 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
|
|||
v2 SliderBarDim = v2{25, BarHeight};
|
||||
|
||||
// Convert Frames To Pixels
|
||||
// TODO(Peter): When the animation system is storing a frame range rather than individual values
|
||||
// come back and use the utility functions here
|
||||
r32 RangeMinPercentPlayable = FrameToPercentRange(AnimationSystem->PlayableRange.Min, TimelineState->VisibleRange);
|
||||
r32 RangeMaxPercentPlayable = FrameToPercentRange(AnimationSystem->PlayableRange.Max, TimelineState->VisibleRange);
|
||||
v2 RangeMinSliderMin = v2{BarBounds.Min.x + (RangeMinPercentPlayable * Width(BarBounds)), BarBounds.Min.y};
|
||||
v2 RangeMaxSliderMin = v2{BarBounds.Min.x + (RangeMaxPercentPlayable * Width(BarBounds)) - 25, BarBounds.Min.y};
|
||||
r32 VisibleMinPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Min, AnimationSystem->PlayableRange);
|
||||
r32 VisibleMaxPercentPlayable = FrameToPercentRange(TimelineState->VisibleRange.Max, AnimationSystem->PlayableRange);
|
||||
v2 RangeMinSliderMin = v2{BarBounds.Min.x + (VisibleMinPercentPlayable * Width(BarBounds)), BarBounds.Min.y};
|
||||
v2 RangeMaxSliderMin = v2{BarBounds.Min.x + (VisibleMaxPercentPlayable * Width(BarBounds)) - 25, BarBounds.Min.y};
|
||||
|
||||
if (MouseButtonHeldDown(Mouse.LeftButtonState) ||
|
||||
MouseButtonTransitionedUp(Mouse.LeftButtonState))
|
||||
|
@ -399,13 +379,13 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
|
|||
PushRenderQuad2D(RenderBuffer, RangeMaxSliderMin, RangeMaxSliderMax, v4{.8f, .8f, .8f, 1.f});
|
||||
|
||||
// Convert Pixels Back To Frames and store
|
||||
RangeMinPercentPlayable = (RangeMinSliderMin.x - BarBounds.Min.x) / BarWidth;
|
||||
RangeMaxPercentPlayable = (RangeMaxSliderMax.x - BarBounds.Min.x) / BarWidth;
|
||||
VisibleMinPercentPlayable = (RangeMinSliderMin.x - BarBounds.Min.x) / BarWidth;
|
||||
VisibleMaxPercentPlayable = (RangeMaxSliderMax.x - BarBounds.Min.x) / BarWidth;
|
||||
u32 VisibleFrameCount = GetFrameCount(AnimationSystem->PlayableRange);
|
||||
Result.Min = RangeMinPercentPlayable * VisibleFrameCount;
|
||||
Result.Max = RangeMaxPercentPlayable * VisibleFrameCount;
|
||||
Result.Min = VisibleMinPercentPlayable * VisibleFrameCount;
|
||||
Result.Max = VisibleMaxPercentPlayable * VisibleFrameCount;
|
||||
|
||||
if (MouseButtonTransitionedUp(Mouse.LeftButtonState))
|
||||
if (MouseButtonTransitionedUp(Mouse.LeftButtonState))
|
||||
{
|
||||
TimelineState->VisibleRange = Result;
|
||||
}
|
||||
|
@ -413,6 +393,35 @@ DrawTimelineRangeBar (animation_system* AnimationSystem, animation_timeline_stat
|
|||
return Result;
|
||||
}
|
||||
|
||||
#define LAYER_HEIGHT 52
|
||||
|
||||
internal void
|
||||
DrawLayerMenu(animation_system* AnimationSystem, rect PanelDim, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||
{
|
||||
v2 LayerDim = { Width(PanelDim), LAYER_HEIGHT };
|
||||
v2 LayerListMin = PanelDim.Min + v2{0, 24};
|
||||
for (u32 LayerIndex = 0; LayerIndex < AnimationSystem->LayersCount; LayerIndex++)
|
||||
{
|
||||
anim_layer* Layer = AnimationSystem->Layers + LayerIndex;
|
||||
rect LayerBounds = {0};
|
||||
LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * LayerIndex) };
|
||||
LayerBounds.Max = LayerBounds.Min + LayerDim;
|
||||
|
||||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState) &&
|
||||
PointIsInRect(Mouse.Pos, LayerBounds))
|
||||
{
|
||||
State->SelectedAnimationLayer = LayerIndex;
|
||||
}
|
||||
|
||||
v2 LayerTextPos = { LayerBounds.Min.x + 6, LayerBounds.Max.y - 16};
|
||||
if (State->SelectedAnimationLayer == LayerIndex)
|
||||
{
|
||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(LayerBounds), 1, WhiteV4);
|
||||
}
|
||||
DrawString(RenderBuffer, Layer->Name, State->Interface.Font, LayerTextPos, WhiteV4);
|
||||
}
|
||||
}
|
||||
|
||||
internal rect
|
||||
DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range VisibleFrames, rect TimelineBounds, render_command_buffer* RenderBuffer)
|
||||
{
|
||||
|
@ -428,8 +437,9 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range V
|
|||
r32 EndFramePercent = FrameToPercentRange(ClampedBlockEndFrame, VisibleFrames);
|
||||
r32 EndPosition = TimelineWidth * EndFramePercent;
|
||||
|
||||
BlockBounds.Min = TimelineBounds.Min + v2{StartPosition, 25};
|
||||
BlockBounds.Max = TimelineBounds.Min + v2{EndPosition, 75};
|
||||
r32 LayerYOffset = LAYER_HEIGHT * AnimationBlock.Layer;
|
||||
BlockBounds.Min = TimelineBounds.Min + v2{StartPosition, LayerYOffset};
|
||||
BlockBounds.Max = TimelineBounds.Min + v2{EndPosition, LayerYOffset + LAYER_HEIGHT};
|
||||
|
||||
PushRenderQuad2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, BlockColor);
|
||||
PushRenderBoundingBox2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, 1, WhiteV4);
|
||||
|
@ -437,27 +447,6 @@ DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range V
|
|||
return BlockBounds;
|
||||
}
|
||||
|
||||
internal void
|
||||
DrawLayerMenu(animation_system* AnimationSystem, rect PanelDim, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||
{
|
||||
string TempString = MakeString(PushArray(&State->Transient, char, 256), 256);
|
||||
v2 LayerDim = { Width(PanelDim), 32 };
|
||||
|
||||
v2 LayerListMin = PanelDim.Min + v2{0, 32};
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
PrintF(&TempString, "Layer %d", i);
|
||||
|
||||
rect LayerBounds = {0};
|
||||
LayerBounds.Min = { LayerListMin.x, LayerListMin.y + (LayerDim.y * i) };
|
||||
LayerBounds.Max = LayerBounds.Min + LayerDim;
|
||||
|
||||
v2 LayerTextPos = LayerBounds.Min + v2{6, 4};
|
||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(LayerBounds), 1, WhiteV4);
|
||||
DrawString(RenderBuffer, TempString, State->Interface.Font, LayerTextPos, WhiteV4);
|
||||
}
|
||||
}
|
||||
|
||||
internal gs_list_handle
|
||||
DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_state* TimelineState, rect PanelBounds, gs_list_handle SelectedBlockHandle, render_command_buffer* RenderBuffer, app_state* State, mouse_state Mouse)
|
||||
{
|
||||
|
@ -499,7 +488,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
|||
for (u32 i = 0; i < AnimationSystem->Blocks.Used; i++)
|
||||
{
|
||||
gs_list_entry<animation_block>* AnimationBlockEntry = AnimationSystem->Blocks.GetEntryAtIndex(i);
|
||||
if (AnimationBlockEntry->Free.NextFreeEntry != 0) { continue; }
|
||||
if (EntryIsFree(AnimationBlockEntry)) { continue; }
|
||||
|
||||
gs_list_handle CurrentBlockHandle = AnimationBlockEntry->Handle;
|
||||
animation_block AnimationBlockAt = AnimationBlockEntry->Value;
|
||||
|
@ -542,25 +531,11 @@ DrawAnimationTimeline (animation_system* AnimationSystem, animation_timeline_sta
|
|||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(FrameBarBounds), 1.f, TealV4);
|
||||
PushRenderBoundingBox2D(RenderBuffer, RectExpand(TimelineBounds), 1.f, PinkV4);
|
||||
|
||||
return Result;
|
||||
|
||||
|
||||
|
||||
{
|
||||
r32 FirstPlayablePercentX = FrameToPercentRange(AnimationSystem->PlayableRange.Min, AdjustedViewRange);
|
||||
r32 LastPlayablePercentX = FrameToPercentRange(AnimationSystem->PlayableRange.Max, AdjustedViewRange);
|
||||
|
||||
v2 PlayableMin = v2{(FirstPlayablePercentX * AnimationPanelWidth) + PanelBounds.Min.x, PanelBounds.Min.y };
|
||||
v2 PlayableMax = v2{(LastPlayablePercentX * AnimationPanelWidth) + PanelBounds.Min.x, PanelBounds.Max.y };
|
||||
|
||||
|
||||
PushRenderQuad2D(RenderBuffer, PlayableMin, PlayableMax, v4{.22f, .22f, .22f, 1.f});
|
||||
}
|
||||
|
||||
if (MouseDownAndNotHandled && PointIsInRect(Mouse.Pos, TimelineBounds))
|
||||
{
|
||||
DeselectCurrentAnimationBlock(State);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -611,7 +586,7 @@ DrawAnimationClipsList(rect PanelBounds, mouse_state Mouse, render_command_buffe
|
|||
if (MouseButtonTransitionedDown(Mouse.LeftButtonState)
|
||||
&& PointIsInRect(Mouse.DownPos, ElementBounds))
|
||||
{
|
||||
AddAnimationBlockAtCurrentTime(i + 1, &State->AnimationSystem);
|
||||
AddAnimationBlockAtCurrentTime(i + 1, State->SelectedAnimationLayer, &State->AnimationSystem);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue