shipping time
This commit is contained in:
parent
6b137154bc
commit
963415335b
|
@ -149,8 +149,6 @@ Editor_Render(app_state* State, context* Context, render_command_buffer* RenderB
|
||||||
}
|
}
|
||||||
|
|
||||||
Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext);
|
Context->GeneralWorkQueue->CompleteQueueWork(Context->GeneralWorkQueue, Context->ThreadContext);
|
||||||
ResetWorkQueue(Context->GeneralWorkQueue);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1534,7 +1534,10 @@ ui_BeginList(ui_interface* Interface, gs_string Text, u32 ViewportRows, u32 Elem
|
||||||
s32 ScrollableElements = Max(0, ElementCount - ViewportRows);
|
s32 ScrollableElements = Max(0, ElementCount - ViewportRows);
|
||||||
ui_widget_retained_state* ViewportState = ui_GetOrCreateRetainedState(Interface, ViewportLayout);
|
ui_widget_retained_state* ViewportState = ui_GetOrCreateRetainedState(Interface, ViewportLayout);
|
||||||
ViewportState->ChildrenDrawOffset.x = 0;
|
ViewportState->ChildrenDrawOffset.x = 0;
|
||||||
ViewportState->ChildrenDrawOffset.y = ((1.0f - State->InitialValueR32) * (r32)(ScrollableElements + 1)) * ViewportLayout->RowHeight;
|
r32 BaseOffset = Rect2Height(ViewportLayout->Bounds) - ViewportLayout->RowHeight;
|
||||||
|
r32 ScrollPct = 1.0 - State->InitialValueR32;
|
||||||
|
r32 ScrollOffset = ScrollPct * ViewportLayout->RowHeight * ScrollableElements;
|
||||||
|
ViewportState->ChildrenDrawOffset.y = BaseOffset + ScrollOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
|
|
@ -19,6 +19,12 @@ struct animation_timeline_state
|
||||||
animation_handle NextActiveAnim;
|
animation_handle NextActiveAnim;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AnimationTimeline_SelectLayer(animation_timeline_state* TLState, s32 Layer)
|
||||||
|
{
|
||||||
|
TLState->SelectedAnimationLayer = Layer;
|
||||||
|
}
|
||||||
|
|
||||||
inline u32
|
inline u32
|
||||||
GetFrameFromPointInAnimationPanel(v2 Point, rect2 PanelBounds, frame_range VisibleRange)
|
GetFrameFromPointInAnimationPanel(v2 Point, rect2 PanelBounds, frame_range VisibleRange)
|
||||||
{
|
{
|
||||||
|
@ -266,6 +272,11 @@ AnimationTimeline_AddAnimationBlockCommand(animation_timeline_state* TimelineSta
|
||||||
{
|
{
|
||||||
animation_pattern_handle PatternHandle = Patterns_IndexToHandle(0);
|
animation_pattern_handle PatternHandle = Patterns_IndexToHandle(0);
|
||||||
s32 Layer = TimelineState->SelectedAnimationLayer;
|
s32 Layer = TimelineState->SelectedAnimationLayer;
|
||||||
|
if (Layer < 0)
|
||||||
|
{
|
||||||
|
Layer = Animation_AddLayer(ActiveAnim, MakeString("[New Layer]"), BlendMode_Add, &State->AnimationSystem);
|
||||||
|
AnimationTimeline_SelectLayer(TimelineState, Layer);
|
||||||
|
}
|
||||||
Assert(Layer >= 0);
|
Assert(Layer >= 0);
|
||||||
|
|
||||||
handle NewBlockHandle = Animation_AddBlock(ActiveAnim, StartFrame, EndFrame, PatternHandle, Layer);
|
handle NewBlockHandle = Animation_AddBlock(ActiveAnim, StartFrame, EndFrame, PatternHandle, Layer);
|
||||||
|
@ -472,33 +483,6 @@ DrawLayerMenu(animation_system* AnimationSystem, animation ActiveAnim, ui_interf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal rect2
|
|
||||||
DrawAnimationBlock (animation_block AnimationBlock, v4 BlockColor, frame_range VisibleFrames, rect2 TimelineBounds, render_command_buffer* RenderBuffer)
|
|
||||||
{
|
|
||||||
rect2 BlockBounds = {};
|
|
||||||
|
|
||||||
r32 TimelineWidth = Rect2Width(TimelineBounds);
|
|
||||||
|
|
||||||
u32 ClampedBlockStartFrame = ClampFrameToRange(AnimationBlock.Range.Min, VisibleFrames);
|
|
||||||
r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, VisibleFrames);
|
|
||||||
r32 StartPosition = TimelineWidth * StartFramePercent;
|
|
||||||
|
|
||||||
u32 ClampedBlockEndFrame = ClampFrameToRange(AnimationBlock.Range.Max, VisibleFrames);
|
|
||||||
r32 EndFramePercent = FrameToPercentRange(ClampedBlockEndFrame, VisibleFrames);
|
|
||||||
r32 EndPosition = TimelineWidth * EndFramePercent;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// TODO(pjs): If mouse is on one of the border hot spots, render an off colored square to signal the region is hot
|
|
||||||
|
|
||||||
return BlockBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback)
|
PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback)
|
||||||
{
|
{
|
||||||
Assert(ReturningFrom->TypeIndex == PanelType_FileView);
|
Assert(ReturningFrom->TypeIndex == PanelType_FileView);
|
||||||
|
@ -518,6 +502,8 @@ PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback)
|
||||||
internal void
|
internal void
|
||||||
PlayBar_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
PlayBar_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
animation_system* AnimSystem = &State->AnimationSystem;
|
animation_system* AnimSystem = &State->AnimationSystem;
|
||||||
ui_interface* Interface = &State->Interface;
|
ui_interface* Interface = &State->Interface;
|
||||||
ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("PlayBar Layout"));
|
ui_PushLayout(Interface, Bounds, LayoutDirection_TopDown, MakeString("PlayBar Layout"));
|
||||||
|
@ -548,6 +534,8 @@ PlayBar_Render(animation_timeline_state* TimelineState, rect2 Bounds, panel* Pan
|
||||||
internal void
|
internal void
|
||||||
FrameCount_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
FrameCount_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
ui_interface* Interface = &State->Interface;
|
ui_interface* Interface = &State->Interface;
|
||||||
gs_string TempString = PushString(State->Transient, 256);
|
gs_string TempString = PushString(State->Transient, 256);
|
||||||
|
|
||||||
|
@ -627,6 +615,7 @@ LayerList_DrawLayerButton (ui_interface* Interface, gs_string Name, rect2 Bounds
|
||||||
internal void
|
internal void
|
||||||
LayerList_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
LayerList_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
ui_interface* Interface = &State->Interface;
|
ui_interface* Interface = &State->Interface;
|
||||||
|
|
||||||
ui_FillRect(Interface, Bounds, Interface->Style.PanelBG);
|
ui_FillRect(Interface, Bounds, Interface->Style.PanelBG);
|
||||||
|
@ -658,9 +647,49 @@ LayerList_Render(animation_timeline_state* TimelineState, animation* ActiveAnim,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
TimeRange_RenderBlock (rect2 BlockBounds, u32 BlockIndex, animation* ActiveAnim, handle SelectedBlockHandle, ui_interface* Interface, render_command_buffer* RenderBuffer)
|
||||||
|
{
|
||||||
|
v4 BlockColor = BlackV4;
|
||||||
|
if (SelectedBlockHandle.Index == BlockIndex && SelectedBlockHandle.Generation == ActiveAnim->Blocks_.Generations[BlockIndex])
|
||||||
|
{
|
||||||
|
BlockColor = TealV4;
|
||||||
|
}
|
||||||
|
|
||||||
|
PushRenderQuad2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, BlockColor);
|
||||||
|
PushRenderBoundingBox2D(RenderBuffer, BlockBounds.Min, BlockBounds.Max, 1, WhiteV4);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct block_bounds_lut_entry
|
||||||
|
{
|
||||||
|
rect2 Bounds;
|
||||||
|
u32 Index;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
TimeRange_RenderBlockArray(block_bounds_lut_entry* Blocks, u32* LUT, u32 LUTCount, r32 HeightOffset, animation* ActiveAnim, handle SelectedBlockHandle, handle* DragBlockHandle, ui_interface* Interface, render_command_buffer* RenderBuffer)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < LUTCount; i++)
|
||||||
|
{
|
||||||
|
u32 BlockBoundsIndex = LUT[i];
|
||||||
|
block_bounds_lut_entry Block = Blocks[BlockBoundsIndex];
|
||||||
|
Block.Bounds.Max.y += HeightOffset;
|
||||||
|
|
||||||
|
TimeRange_RenderBlock(Block.Bounds, Block.Index, ActiveAnim, SelectedBlockHandle, Interface, RenderBuffer);
|
||||||
|
|
||||||
|
if (PointIsInRect(Block.Bounds, Interface->Mouse.Pos))
|
||||||
|
{
|
||||||
|
DragBlockHandle->Index = Block.Index;
|
||||||
|
DragBlockHandle->Generation = ActiveAnim->Blocks_.Generations[Block.Index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
TimeRange_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
TimeRange_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
ui_interface* Interface = &State->Interface;
|
ui_interface* Interface = &State->Interface;
|
||||||
|
|
||||||
// TODO(pjs): setting the timeline to show the entire range
|
// TODO(pjs): setting the timeline to show the entire range
|
||||||
|
@ -682,9 +711,25 @@ TimeRange_Render(animation_timeline_state* TimelineState, animation* ActiveAnim,
|
||||||
handle DragBlockHandle = {0};
|
handle DragBlockHandle = {0};
|
||||||
if (ActiveAnim)
|
if (ActiveAnim)
|
||||||
{
|
{
|
||||||
|
u32 BlocksCountMax = ActiveAnim->Blocks_.Count;
|
||||||
|
u32 BlocksCount = 0;
|
||||||
|
block_bounds_lut_entry* Blocks = PushArray(State->Transient, block_bounds_lut_entry, BlocksCountMax);
|
||||||
|
|
||||||
|
u32 FrontBlocksCount = 0;
|
||||||
|
u32* FrontBlocks = PushArray(State->Transient, u32, BlocksCountMax);
|
||||||
|
u32 BackBlocksCount = 0;
|
||||||
|
u32* BackBlocks = PushArray(State->Transient, u32, BlocksCountMax);
|
||||||
|
|
||||||
|
for (u32 l = 0; l < ActiveAnim->Layers.Count; l++)
|
||||||
|
{
|
||||||
|
BlocksCount = 0;
|
||||||
|
FrontBlocksCount = 0;
|
||||||
|
BackBlocksCount = 0;
|
||||||
|
|
||||||
for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++)
|
for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++)
|
||||||
{
|
{
|
||||||
animation_block* AnimationBlockAt = ActiveAnim->Blocks_.Values + i;
|
animation_block* AnimationBlockAt = ActiveAnim->Blocks_.Values + i;
|
||||||
|
if (AnimationBlockAt->Layer != l) continue;
|
||||||
|
|
||||||
// If either end is in the range, we should draw it
|
// If either end is in the range, we should draw it
|
||||||
b32 RangeIsVisible = (FrameIsInRange(ViewRange, AnimationBlockAt->Range.Min) ||
|
b32 RangeIsVisible = (FrameIsInRange(ViewRange, AnimationBlockAt->Range.Min) ||
|
||||||
|
@ -693,21 +738,81 @@ TimeRange_Render(animation_timeline_state* TimelineState, animation* ActiveAnim,
|
||||||
// we should still draw it.
|
// we should still draw it.
|
||||||
RangeIsVisible |= (AnimationBlockAt->Range.Min <= ViewRange.Min &&
|
RangeIsVisible |= (AnimationBlockAt->Range.Min <= ViewRange.Min &&
|
||||||
AnimationBlockAt->Range.Max>= ViewRange.Max);
|
AnimationBlockAt->Range.Max>= ViewRange.Max);
|
||||||
if (RangeIsVisible)
|
if (!RangeIsVisible) continue;
|
||||||
{
|
|
||||||
v4 BlockColor = BlackV4;
|
|
||||||
if (SelectedBlockHandle.Index == i && SelectedBlockHandle.Generation == ActiveAnim->Blocks_.Generations[i])
|
|
||||||
{
|
|
||||||
BlockColor = PinkV4;
|
|
||||||
}
|
|
||||||
rect2 BlockBounds = DrawAnimationBlock(*AnimationBlockAt, BlockColor, ViewRange, Bounds, Interface->RenderBuffer);
|
|
||||||
|
|
||||||
if (PointIsInRect(BlockBounds, Interface->Mouse.Pos))
|
r32 TimelineWidth = Rect2Width(Bounds);
|
||||||
|
|
||||||
|
frame_range BlockAtRange = AnimationBlockAt->Range;
|
||||||
|
u32 ClampedBlockStartFrame = ClampFrameToRange(BlockAtRange.Min, ViewRange);
|
||||||
|
r32 StartFramePercent = FrameToPercentRange(ClampedBlockStartFrame, ViewRange);
|
||||||
|
r32 StartPosition = TimelineWidth * StartFramePercent;
|
||||||
|
|
||||||
|
u32 ClampedBlockEndFrame = ClampFrameToRange(BlockAtRange.Max, ViewRange);
|
||||||
|
r32 EndFramePercent = FrameToPercentRange(ClampedBlockEndFrame, ViewRange);
|
||||||
|
r32 EndPosition = TimelineWidth * EndFramePercent;
|
||||||
|
|
||||||
|
r32 LayerYOffset = LAYER_HEIGHT * AnimationBlockAt->Layer;
|
||||||
|
|
||||||
|
rect2 NewBlockBounds = {};
|
||||||
|
NewBlockBounds.Min = Bounds.Min + v2{StartPosition, LayerYOffset};
|
||||||
|
NewBlockBounds.Max = Bounds.Min + v2{EndPosition, LayerYOffset + LAYER_HEIGHT};
|
||||||
|
|
||||||
|
block_bounds_lut_entry NewBlock = {};
|
||||||
|
NewBlock.Bounds = NewBlockBounds;
|
||||||
|
NewBlock.Index = i;
|
||||||
|
|
||||||
|
// fast (implementation-wise) insert sort.
|
||||||
|
// TODO(PS): probably not great
|
||||||
|
for (u32 j = 0; j < BlocksCount; j++)
|
||||||
{
|
{
|
||||||
DragBlockHandle.Index = i;
|
if (Blocks[j].Bounds.Min.x > NewBlock.Bounds.Min.x)
|
||||||
DragBlockHandle.Generation = ActiveAnim->Blocks_.Generations[i];
|
{
|
||||||
|
block_bounds_lut_entry Old = Blocks[j];
|
||||||
|
Blocks[j] = NewBlock;
|
||||||
|
NewBlock = Old;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Blocks[BlocksCount++] = NewBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockBounds are sorted by their render bounds from left to right
|
||||||
|
// This iterates over them to see if any on the same layer overlap, and if
|
||||||
|
// so, shrinks one of them, putting it in a new list
|
||||||
|
for (u32 i = 0; i < BlocksCount; i++)
|
||||||
|
{
|
||||||
|
if (i % 2 == 0)
|
||||||
|
{
|
||||||
|
BackBlocks[BackBlocksCount++] = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortCandidate = false;
|
||||||
|
block_bounds_lut_entry Block = Blocks[i];
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
block_bounds_lut_entry PrevBlock = Blocks[i - 1];
|
||||||
|
rect2 Union = Rect2Union(PrevBlock.Bounds, Block.Bounds);
|
||||||
|
ShortCandidate |= Rect2Width(Union) > 0;
|
||||||
|
}
|
||||||
|
if (i < BlocksCount - 1)
|
||||||
|
{
|
||||||
|
block_bounds_lut_entry NextBlock = Blocks[i + 1];
|
||||||
|
rect2 Union = Rect2Union(NextBlock.Bounds, Block.Bounds);
|
||||||
|
ShortCandidate |= Rect2Width(Union) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShortCandidate)
|
||||||
|
{
|
||||||
|
FrontBlocks[FrontBlocksCount++] = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BackBlocks[BackBlocksCount++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeRange_RenderBlockArray(Blocks, BackBlocks, BackBlocksCount, 0, ActiveAnim, SelectedBlockHandle, &DragBlockHandle, Interface, RenderBuffer);
|
||||||
|
TimeRange_RenderBlockArray(Blocks, FrontBlocks, FrontBlocksCount, -15, ActiveAnim, SelectedBlockHandle, &DragBlockHandle, Interface, RenderBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,6 +875,7 @@ AnimationTimeline_SetActiveAnimation (animation_handle Handle, animation_timelin
|
||||||
internal void
|
internal void
|
||||||
AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAnim, rect2 Bounds, panel* Panel, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
animation_system* AnimSystem = &State->AnimationSystem;
|
animation_system* AnimSystem = &State->AnimationSystem;
|
||||||
|
|
||||||
animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From;
|
animation_handle ActiveAnimHandle = State->AnimationSystem.ActiveFadeGroup.From;
|
||||||
|
@ -884,9 +990,8 @@ AnimInfoView_Render(animation_timeline_state* TimelineState, animation* ActiveAn
|
||||||
{
|
{
|
||||||
animation_pattern BlockPattern = Patterns_GetPattern(State->Patterns, SelectedBlock->AnimationProcHandle);
|
animation_pattern BlockPattern = Patterns_GetPattern(State->Patterns, SelectedBlock->AnimationProcHandle);
|
||||||
|
|
||||||
ui_BeginRow(Interface, 3);
|
ui_BeginRow(Interface, 2);
|
||||||
ui_Label(Interface, MakeString("Selected Pattern"));
|
ui_Label(Interface, MakeString("Selected Pattern"));
|
||||||
//if (ui_BeginLabeledDropdown(Interface, MakeString("Selected Pattern"), MakeString(BlockPattern.Name, BlockPattern.NameLength)))
|
|
||||||
if (ui_BeginDropdown(Interface, MakeString(BlockPattern.Name, BlockPattern.NameLength)))
|
if (ui_BeginDropdown(Interface, MakeString(BlockPattern.Name, BlockPattern.NameLength)))
|
||||||
{
|
{
|
||||||
Interface->ActiveLayout->Bounds.Max.x += 128.0f;
|
Interface->ActiveLayout->Bounds.Max.x += 128.0f;
|
||||||
|
@ -925,6 +1030,8 @@ GSMetaTag(panel_type_animation_timeline);
|
||||||
internal void
|
internal void
|
||||||
AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
animation_timeline_state* TimelineState = Panel_GetStateStruct(Panel, animation_timeline_state);
|
animation_timeline_state* TimelineState = Panel_GetStateStruct(Panel, animation_timeline_state);
|
||||||
|
|
||||||
animation* ActiveAnim = 0;
|
animation* ActiveAnim = 0;
|
||||||
|
|
|
@ -291,6 +291,13 @@ Patterns_IndexToHandle(s32 Index)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool
|
||||||
|
IsValid(animation_pattern_handle Handle)
|
||||||
|
{
|
||||||
|
bool Result = Handle.IndexPlusOne > 0;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal animation_pattern
|
internal animation_pattern
|
||||||
Patterns_GetPattern(animation_pattern_array Patterns, animation_pattern_handle Handle)
|
Patterns_GetPattern(animation_pattern_array Patterns, animation_pattern_handle Handle)
|
||||||
{
|
{
|
||||||
|
@ -312,7 +319,7 @@ internal animation_block_array
|
||||||
AnimBlockArray_Create(gs_memory_arena* Storage, u32 CountMax)
|
AnimBlockArray_Create(gs_memory_arena* Storage, u32 CountMax)
|
||||||
{
|
{
|
||||||
animation_block_array Result = {0};
|
animation_block_array Result = {0};
|
||||||
Result.CountMax = CountMax;
|
Result.CountMax = Max(CountMax, 32);
|
||||||
Result.Values = PushArray(Storage, animation_block, Result.CountMax);
|
Result.Values = PushArray(Storage, animation_block, Result.CountMax);
|
||||||
Result.Generations = PushArray(Storage, u32, Result.CountMax);
|
Result.Generations = PushArray(Storage, u32, Result.CountMax);
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -359,7 +366,7 @@ internal anim_layer_array
|
||||||
AnimLayerArray_Create(gs_memory_arena* Storage, u32 CountMax)
|
AnimLayerArray_Create(gs_memory_arena* Storage, u32 CountMax)
|
||||||
{
|
{
|
||||||
anim_layer_array Result = {0};
|
anim_layer_array Result = {0};
|
||||||
Result.CountMax = CountMax;
|
Result.CountMax = Max(CountMax, 32);
|
||||||
Result.Values = PushArray(Storage, anim_layer, Result.CountMax);
|
Result.Values = PushArray(Storage, anim_layer, Result.CountMax);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -409,6 +416,8 @@ AnimationArray_Push(animation_array* Array, animation Value)
|
||||||
internal animation*
|
internal animation*
|
||||||
AnimationArray_Get(animation_array Array, animation_handle Handle)
|
AnimationArray_Get(animation_array Array, animation_handle Handle)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
animation* Result = 0;
|
animation* Result = 0;
|
||||||
if (IsValid(Handle) && Handle.Index < (s32)Array.Count)
|
if (IsValid(Handle) && Handle.Index < (s32)Array.Count)
|
||||||
{
|
{
|
||||||
|
@ -541,6 +550,13 @@ SecondsToFrames(r32 Seconds, animation_system System)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline frame_range
|
||||||
|
FrameRange_Overlap(frame_range A, frame_range B)
|
||||||
|
{
|
||||||
|
frame_range Result = {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
FrameIsInRange(frame_range Range, s32 Frame)
|
FrameIsInRange(frame_range Range, s32 Frame)
|
||||||
{
|
{
|
||||||
|
@ -679,6 +695,8 @@ AnimationSystem_CalculateAnimationFrame(animation_system* System,
|
||||||
animation* Animation,
|
animation* Animation,
|
||||||
gs_memory_arena* Arena)
|
gs_memory_arena* Arena)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
animation_frame Result = {0};
|
animation_frame Result = {0};
|
||||||
Result.LayersCount = Animation->Layers.Count;
|
Result.LayersCount = Animation->Layers.Count;
|
||||||
Result.Layers = PushArray(Arena, animation_layer_frame, Result.LayersCount);
|
Result.Layers = PushArray(Arena, animation_layer_frame, Result.LayersCount);
|
||||||
|
@ -793,5 +811,12 @@ AnimationSystem_NeedsRender(animation_system System)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline r32
|
||||||
|
AnimationSystem_GetCurrentTime(animation_system System)
|
||||||
|
{
|
||||||
|
r32 Result = System.CurrentFrame * System.SecondsPerFrame;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
#define FOLDHAUS_ANIMATION
|
#define FOLDHAUS_ANIMATION
|
||||||
#endif // FOLDHAUS_ANIMATION
|
#endif // FOLDHAUS_ANIMATION
|
|
@ -122,6 +122,7 @@ AnimationSystem_BeginRenderBlockToLedBuffer(animation_system* System, animation_
|
||||||
r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame;
|
r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame;
|
||||||
|
|
||||||
animation_pattern Pattern = Patterns_GetPattern(Patterns, Block.AnimationProcHandle);
|
animation_pattern Pattern = Patterns_GetPattern(Patterns, Block.AnimationProcHandle);
|
||||||
|
Assert(Pattern.Proc);
|
||||||
|
|
||||||
if (System->Multithreaded && Pattern.Multithreaded)
|
if (System->Multithreaded && Pattern.Multithreaded)
|
||||||
{
|
{
|
||||||
|
@ -182,6 +183,8 @@ RenderAnimationToLedBuffer (animation_system* System,
|
||||||
gs_memory_arena* Transient,
|
gs_memory_arena* Transient,
|
||||||
context Context)
|
context Context)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
led_buffer AccBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient);
|
led_buffer AccBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient);
|
||||||
|
|
||||||
// Create the LayerLEDBuffers
|
// Create the LayerLEDBuffers
|
||||||
|
@ -266,8 +269,7 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
s32 CurrentFrame = System->CurrentFrame;
|
r32 FrameTime = AnimationSystem_GetCurrentTime(*System);
|
||||||
r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
animation_array Animations = System->Animations;
|
animation_array Animations = System->Animations;
|
||||||
|
|
|
@ -82,12 +82,10 @@ AnimParser_Parse(gs_string File, gs_memory_arena* Arena, animation_pattern_array
|
||||||
{
|
{
|
||||||
Result.Name = Parser_ReadStringValue(&Parser, AnimField_AnimName);
|
Result.Name = Parser_ReadStringValue(&Parser, AnimField_AnimName);
|
||||||
|
|
||||||
Result.Layers.CountMax = Parser_ReadU32Value(&Parser, AnimField_LayersCount);
|
u32 LayersNeeded = Parser_ReadU32Value(&Parser, AnimField_LayersCount);
|
||||||
Result.Layers.Values = PushArray(Arena, anim_layer, Result.Layers.CountMax);
|
u32 BlocksNeeded = Parser_ReadU32Value(&Parser, AnimField_BlocksCount);
|
||||||
|
Result.Layers = AnimLayerArray_Create(Arena, LayersNeeded);
|
||||||
Result.Blocks_.CountMax = Parser_ReadU32Value(&Parser, AnimField_BlocksCount);
|
Result.Blocks_ = AnimBlockArray_Create(Arena, BlocksNeeded);
|
||||||
Result.Blocks_.Generations = PushArray(Arena, u32, Result.Blocks_.CountMax);
|
|
||||||
Result.Blocks_.Values = PushArray(Arena, animation_block, Result.Blocks_.CountMax);
|
|
||||||
|
|
||||||
if (Parser_ReadOpenStruct(&Parser, AnimField_PlayableRange))
|
if (Parser_ReadOpenStruct(&Parser, AnimField_PlayableRange))
|
||||||
{
|
{
|
||||||
|
@ -169,7 +167,7 @@ AnimParser_Parse(gs_string File, gs_memory_arena* Arena, animation_pattern_array
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Assert(IsValid(Block.AnimationProcHandle));
|
||||||
if (Parser_ReadCloseStruct(&Parser))
|
if (Parser_ReadCloseStruct(&Parser))
|
||||||
{
|
{
|
||||||
AnimBlockArray_Push(&Result.Blocks_, Block);
|
AnimBlockArray_Push(&Result.Blocks_, Block);
|
||||||
|
@ -200,6 +198,7 @@ AnimationSystem_LoadAnimationFromFile(animation_system* System, animation_patter
|
||||||
{
|
{
|
||||||
animation NewAnim = AnimParser_Parse(AnimFile.Data, System->Storage, AnimPatterns);
|
animation NewAnim = AnimParser_Parse(AnimFile.Data, System->Storage, AnimPatterns);
|
||||||
NewAnim.FileInfo = AnimFile.FileInfo;
|
NewAnim.FileInfo = AnimFile.FileInfo;
|
||||||
|
NewAnim.FileInfo.Path = PushStringF(System->Storage, AnimFile.FileInfo.Path.Length, "%S", AnimFile.FileInfo.Path).ConstString;
|
||||||
NewAnimHandle = AnimationArray_Push(&System->Animations, NewAnim);
|
NewAnimHandle = AnimationArray_Push(&System->Animations, NewAnim);
|
||||||
}
|
}
|
||||||
return NewAnimHandle;
|
return NewAnimHandle;
|
||||||
|
|
|
@ -276,7 +276,7 @@ ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileTe
|
||||||
|
|
||||||
Assembly->Name = Parser_ReadStringValue(&Parser, AssemblyField_AssemblyName);
|
Assembly->Name = Parser_ReadStringValue(&Parser, AssemblyField_AssemblyName);
|
||||||
Assembly->Scale = Parser_ReadR32Value(&Parser, AssemblyField_AssemblyScale);
|
Assembly->Scale = Parser_ReadR32Value(&Parser, AssemblyField_AssemblyScale);
|
||||||
Assembly->Center = Parser_ReadV3Value(&Parser, AssemblyField_AssemblyCenter);
|
Assembly->Center = Parser_ReadV3Value(&Parser, AssemblyField_AssemblyCenter) * Assembly->Scale;
|
||||||
Assembly->StripCount = Parser_ReadU32Value(&Parser, AssemblyField_LedStripCount);
|
Assembly->StripCount = Parser_ReadU32Value(&Parser, AssemblyField_LedStripCount);
|
||||||
Assembly->Strips = PushArray(&Assembly->Arena, v2_strip, Assembly->StripCount);
|
Assembly->Strips = PushArray(&Assembly->Arena, v2_strip, Assembly->StripCount);
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,22 @@
|
||||||
|
|
||||||
RELOAD_STATIC_DATA(ReloadStaticData)
|
RELOAD_STATIC_DATA(ReloadStaticData)
|
||||||
{
|
{
|
||||||
app_state* State = (app_state*)Context.MemoryBase;
|
|
||||||
|
|
||||||
GlobalDebugServices = DebugServices;
|
GlobalDebugServices = DebugServices;
|
||||||
|
|
||||||
|
if (AppReady)
|
||||||
|
{
|
||||||
|
app_state* State = (app_state*)Context.MemoryBase;
|
||||||
State->PanelSystem.PanelDefs = GlobalPanelDefs;
|
State->PanelSystem.PanelDefs = GlobalPanelDefs;
|
||||||
State->PanelSystem.PanelDefsCount = GlobalPanelDefsCount;
|
State->PanelSystem.PanelDefsCount = GlobalPanelDefsCount;
|
||||||
|
|
||||||
|
gs_data UserData = State->UserSpaceDesc.UserData;
|
||||||
|
State->UserSpaceDesc = BlumenLumen_UserSpaceCreate();
|
||||||
|
if (UserData.Memory && !State->UserSpaceDesc.UserData.Memory)
|
||||||
|
{
|
||||||
|
State->UserSpaceDesc.UserData = UserData;
|
||||||
|
}
|
||||||
US_LoadPatterns(&State->UserSpaceDesc, State, Context);
|
US_LoadPatterns(&State->UserSpaceDesc, State, Context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INITIALIZE_APPLICATION(InitializeApplication)
|
INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
|
@ -38,6 +47,8 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
AnimSysDesc.SecondsPerFrame = 1.0f / 24.0f;
|
AnimSysDesc.SecondsPerFrame = 1.0f / 24.0f;
|
||||||
State->AnimationSystem = AnimationSystem_Init(AnimSysDesc);
|
State->AnimationSystem = AnimationSystem_Init(AnimSysDesc);
|
||||||
|
|
||||||
|
if (!Context.Headless)
|
||||||
|
{
|
||||||
interface_config IConfig = {0};
|
interface_config IConfig = {0};
|
||||||
IConfig.FontSize = 14;
|
IConfig.FontSize = 14;
|
||||||
IConfig.PanelBG = v4{ .3f, .3f, .3f, 1.f };
|
IConfig.PanelBG = v4{ .3f, .3f, .3f, 1.f };
|
||||||
|
@ -52,6 +63,10 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
IConfig.Margin = v2{5, 5};
|
IConfig.Margin = v2{5, 5};
|
||||||
State->Interface = ui_InterfaceCreate(Context, IConfig, &State->Permanent);
|
State->Interface = ui_InterfaceCreate(Context, IConfig, &State->Permanent);
|
||||||
|
|
||||||
|
PanelSystem_Init(&State->PanelSystem, GlobalPanelDefs, GlobalPanelDefsCount, &State->Permanent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
State->SACN = SACN_Initialize(Context);
|
State->SACN = SACN_Initialize(Context);
|
||||||
|
|
||||||
State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128);
|
State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128);
|
||||||
|
@ -59,17 +74,14 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
State->AssemblyDebugState.Brightness = 255;
|
State->AssemblyDebugState.Brightness = 255;
|
||||||
State->AssemblyDebugState.Override = ADS_Override_None;
|
State->AssemblyDebugState.Override = ADS_Override_None;
|
||||||
|
|
||||||
GlobalDebugServices->Interface.RenderSculpture = true;
|
|
||||||
|
|
||||||
PanelSystem_Init(&State->PanelSystem, GlobalPanelDefs, GlobalPanelDefsCount, &State->Permanent);
|
|
||||||
|
|
||||||
State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext);
|
State->Modes = OperationModeSystemInit(&State->Permanent, Context.ThreadContext);
|
||||||
|
|
||||||
State->UserSpaceDesc = BlumenLumen_UserSpaceCreate();
|
ReloadStaticData(Context, GlobalDebugServices, true);
|
||||||
|
|
||||||
ReloadStaticData(Context, GlobalDebugServices);
|
|
||||||
US_CustomInit(&State->UserSpaceDesc, State, Context);
|
US_CustomInit(&State->UserSpaceDesc, State, Context);
|
||||||
|
|
||||||
|
GlobalDebugServices->Interface.RenderSculpture = true;
|
||||||
|
|
||||||
|
if (!Context.Headless)
|
||||||
{
|
{
|
||||||
// NOTE(pjs): This just sets up the default panel layout
|
// NOTE(pjs): This just sets up the default panel layout
|
||||||
panel* RootPanel = PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, Context);
|
panel* RootPanel = PanelSystem_PushPanel(&State->PanelSystem, PanelType_SculptureView, State, Context);
|
||||||
|
@ -92,7 +104,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
State->RunEditor = true;
|
State->RunEditor = !Context.Headless;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -152,6 +164,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
{
|
{
|
||||||
Editor_Render(State, Context, RenderBuffer);
|
Editor_Render(State, Context, RenderBuffer);
|
||||||
}
|
}
|
||||||
|
ResetWorkQueue(Context->GeneralWorkQueue);
|
||||||
|
|
||||||
Assert(State->UserSpaceDesc.UserData.Memory != 0);
|
Assert(State->UserSpaceDesc.UserData.Memory != 0);
|
||||||
BuildAssemblyData(State, *Context, OutputData);
|
BuildAssemblyData(State, *Context, OutputData);
|
||||||
|
|
|
@ -95,6 +95,7 @@ LoadAssembly(gs_const_string Path, app_state* State, context Context)
|
||||||
|
|
||||||
#include "engine/user_space.cpp"
|
#include "engine/user_space.cpp"
|
||||||
|
|
||||||
|
#include "ss_blumen_lumen/sdf.h"
|
||||||
#include "patterns/blumen_patterns.h"
|
#include "patterns/blumen_patterns.h"
|
||||||
#include "ss_blumen_lumen/blumen_lumen.cpp"
|
#include "ss_blumen_lumen/blumen_lumen.cpp"
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ typedef INITIALIZE_APPLICATION(initialize_application);
|
||||||
#define UPDATE_AND_RENDER(name) void name(context* Context, input_queue InputQueue, render_command_buffer* RenderBuffer, addressed_data_buffer_list* OutputData)
|
#define UPDATE_AND_RENDER(name) void name(context* Context, input_queue InputQueue, render_command_buffer* RenderBuffer, addressed_data_buffer_list* OutputData)
|
||||||
typedef UPDATE_AND_RENDER(update_and_render);
|
typedef UPDATE_AND_RENDER(update_and_render);
|
||||||
|
|
||||||
#define RELOAD_STATIC_DATA(name) void name(context Context, debug_services* DebugServices)
|
#define RELOAD_STATIC_DATA(name) void name(context Context, debug_services* DebugServices, bool AppReady)
|
||||||
typedef RELOAD_STATIC_DATA(reload_static_data);
|
typedef RELOAD_STATIC_DATA(reload_static_data);
|
||||||
|
|
||||||
#define CLEANUP_APPLICATION(name) void name(context Context, addressed_data_buffer_list* OutputData)
|
#define CLEANUP_APPLICATION(name) void name(context Context, addressed_data_buffer_list* OutputData)
|
||||||
|
@ -213,6 +213,7 @@ struct context
|
||||||
|
|
||||||
b32 WindowIsVisible;
|
b32 WindowIsVisible;
|
||||||
rect2 WindowBounds;
|
rect2 WindowBounds;
|
||||||
|
r64 TotalTime;
|
||||||
r32 DeltaTime;
|
r32 DeltaTime;
|
||||||
mouse_state Mouse;
|
mouse_state Mouse;
|
||||||
|
|
||||||
|
@ -236,6 +237,9 @@ struct context
|
||||||
|
|
||||||
system_time SystemTime_Last;
|
system_time SystemTime_Last;
|
||||||
system_time SystemTime_Current;
|
system_time SystemTime_Current;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool Headless;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FOLDHAUS_PLATFORM_H
|
#define FOLDHAUS_PLATFORM_H
|
||||||
|
|
|
@ -286,9 +286,9 @@ Fbm3D(v3 P, r32 T)
|
||||||
|
|
||||||
F += 0.500000f * Noise3D(Pp + Tt); Pp = Pp * 2.02;
|
F += 0.500000f * Noise3D(Pp + Tt); Pp = Pp * 2.02;
|
||||||
F += 0.031250f * Noise3D(Pp); Pp = Pp * 2.01;
|
F += 0.031250f * Noise3D(Pp); Pp = Pp * 2.01;
|
||||||
F += 0.250000f * Noise3D(Pp); Pp = Pp * 2.03;
|
F += 0.250000f * Noise3D(Pp - Tt); Pp = Pp * 2.03;
|
||||||
F += 0.125000f * Noise3D(Pp); Pp = Pp * 2.01;
|
F += 0.125000f * Noise3D(Pp); Pp = Pp * 2.01;
|
||||||
F += 0.062500f * Noise3D(Pp); Pp = Pp * 2.04;
|
F += 0.062500f * Noise3D(Pp + Tt); Pp = Pp * 2.04;
|
||||||
F += 0.015625f * Noise3D(Pp + Tv);
|
F += 0.015625f * Noise3D(Pp + Tv);
|
||||||
|
|
||||||
F = F / 0.984375f;
|
F = F / 0.984375f;
|
||||||
|
@ -319,49 +319,6 @@ Voronoise(v2 P, r32 U, r32 V)
|
||||||
return A.x / A.y;
|
return A.x / A.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4 FlowerAColors[FLOWER_COLORS_COUNT] = {
|
|
||||||
{ 232 / 255.f, 219 / 255.f, 88 / 255.f },
|
|
||||||
{ 232 / 255.f, 219 / 255.f, 88 / 255.f },
|
|
||||||
{ 232 / 255.f, 219 / 255.f, 88 / 255.f },
|
|
||||||
{ 147 / 255.f, 75 / 255.f, 176 / 255.f },
|
|
||||||
{ 193 / 255.f, 187 / 255.f, 197 / 255.f },
|
|
||||||
{ 223 / 255.f, 190 / 255.f, 49 / 255.f },
|
|
||||||
{ 198 / 255.f, 76 / 255.f, 65 / 255.f },
|
|
||||||
{ 198 / 255.f, 76 / 255.f, 65 / 255.f },
|
|
||||||
{ 198 / 255.f, 76 / 255.f, 65 / 255.f },
|
|
||||||
{ 226 / 255.f, 200 / 255.f, 17 / 255.f },
|
|
||||||
{ 116 / 255.f, 126 / 255.f, 39 / 255.f },
|
|
||||||
{ 61 / 255.f, 62 / 255.f, 31 / 255.f }
|
|
||||||
};
|
|
||||||
v4 FlowerBColors[FLOWER_COLORS_COUNT] = {
|
|
||||||
{ 62 / 255.f, 56 / 255.f, 139 / 255.f },
|
|
||||||
{ 93 / 255.f, 87 / 255.f, 164 / 255.f },
|
|
||||||
{ 93 / 255.f, 87 / 255.f, 164 / 255.f },
|
|
||||||
{ 93 / 255.f, 87 / 255.f, 164 / 255.f },
|
|
||||||
{ 155 / 255.f, 140 / 255.f, 184 / 255.f },
|
|
||||||
{ 191 / 255.f, 201 / 255.f, 204 / 255.f },
|
|
||||||
{ 45 / 255.f, 31 / 255.f, 116 / 255.f },
|
|
||||||
{ 201 / 255.f, 196 / 255.f, 156 / 255.f },
|
|
||||||
{ 191 / 255.f, 175 / 255.f, 109 / 255.f },
|
|
||||||
{ 186 / 255.f, 176 / 255.f, 107 / 255.f },
|
|
||||||
{ 89 / 255.f, 77 / 255.f, 17 / 255.f },
|
|
||||||
{ 47 / 255.f, 49 / 255.f, 18 / 255.f },
|
|
||||||
};
|
|
||||||
v4 FlowerCColors[FLOWER_COLORS_COUNT] = {
|
|
||||||
{ 220 / 255.f, 217 / 255.f, 210 / 255.f },
|
|
||||||
{ 220 / 255.f, 217 / 255.f, 210 / 255.f },
|
|
||||||
{ 220 / 255.f, 217 / 255.f, 210 / 255.f },
|
|
||||||
{ 225 / 255.f, 193 / 255.f, 110 / 255.f },
|
|
||||||
{ 225 / 255.f, 193 / 255.f, 110 / 255.f },
|
|
||||||
{ 227 / 255.f, 221 / 255.f, 214 / 255.f },
|
|
||||||
{ 227 / 255.f, 221 / 255.f, 214 / 255.f },
|
|
||||||
{ 230 / 255.f, 218 / 255.f, 187 / 255.f },
|
|
||||||
{ 230 / 255.f, 218 / 255.f, 187 / 255.f },
|
|
||||||
{ 172 / 255.f, 190 / 255.f, 211 / 255.f },
|
|
||||||
{ 172 / 255.f, 190 / 255.f, 211 / 255.f },
|
|
||||||
{ 172 / 255.f, 190 / 255.f, 211 / 255.f },
|
|
||||||
};
|
|
||||||
|
|
||||||
internal pixel
|
internal pixel
|
||||||
V4ToRGBPixel(v4 C)
|
V4ToRGBPixel(v4 C)
|
||||||
{
|
{
|
||||||
|
@ -410,166 +367,6 @@ GetColor(v4* Colors, u32 ColorsCount, r32 Percent)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
|
||||||
SolidColorPattern(led_buffer* Leds, led_buffer_range Range, pixel Color)
|
|
||||||
{
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
|
||||||
{
|
|
||||||
Leds->Colors[LedIndex] = Color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_Blue(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
pixel Blue = pixel{0, 0, 255};
|
|
||||||
SolidColorPattern(Leds, Range, Blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_Green(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
pixel Green = pixel{0, 255, 0};
|
|
||||||
SolidColorPattern(Leds, Range, Green);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_FlowerColors(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
r32 CycleTime = 10;
|
|
||||||
r32 CyclePercent = ModR32(Time, CycleTime) / CycleTime;
|
|
||||||
|
|
||||||
v4 CA = GetColor(FlowerAColors, FLOWER_COLORS_COUNT, CyclePercent);
|
|
||||||
v4 CB = GetColor(FlowerAColors, FLOWER_COLORS_COUNT, 1.0f - CyclePercent);
|
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 P = Leds->Positions[LedIndex];
|
|
||||||
r32 Pct = (Abs(ModR32(P.y, 150) / 150) + CycleTime) * PiR32;
|
|
||||||
|
|
||||||
r32 APct = RemapR32(SinR32(Pct), -1, 1, 0, 1);
|
|
||||||
Leds->Colors[LedIndex] = PixelMix(APct, CA, CB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
TestPatternOne(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
led_strip_list BlumenStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Blumen Lumen"), Transient);
|
|
||||||
led_strip_list RadiaStrips = AssemblyStripsGetWithTagValue(Assembly, ConstString("assembly"), ConstString("Radialumia"), Transient);
|
|
||||||
|
|
||||||
for (u32 i = 0; i < BlumenStrips.Count; i++)
|
|
||||||
{
|
|
||||||
u32 StripIndex = BlumenStrips.StripIndices[i];
|
|
||||||
v2_strip StripAt = Assembly.Strips[StripIndex];
|
|
||||||
|
|
||||||
for (u32 j = 0; j < StripAt.LedCount; j++)
|
|
||||||
{
|
|
||||||
u32 LedIndex = StripAt.LedLUT[j];
|
|
||||||
Leds->Colors[LedIndex] = { 255, 0, 0 };
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u32 i = 0; i < RadiaStrips.Count; i++)
|
|
||||||
{
|
|
||||||
u32 StripIndex = RadiaStrips.StripIndices[i];
|
|
||||||
v2_strip StripAt = Assembly.Strips[StripIndex];
|
|
||||||
|
|
||||||
for (u32 j = 0; j < StripAt.LedCount; j++)
|
|
||||||
{
|
|
||||||
u32 LedIndex = StripAt.LedLUT[j];
|
|
||||||
Leds->Colors[LedIndex] = { 0, 255, 0 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
TestPatternTwo(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
r32 PeriodicTime = (Time / PiR32) * 2;
|
|
||||||
|
|
||||||
r32 ZeroOneSin = (SinR32(PeriodicTime) * .5f) + .5f;
|
|
||||||
r32 ZeroOneCos = (CosR32(PeriodicTime) * .5f) + .5f;
|
|
||||||
pixel Color = { (u8)(ZeroOneSin * 255), 0, (u8)(ZeroOneCos * 255) };
|
|
||||||
|
|
||||||
v4 Center = v4{0, 0, 0, 1};
|
|
||||||
r32 ThetaZ = Time / 2;
|
|
||||||
v4 Normal = v4{CosR32(ThetaZ), 0, SinR32(ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
|
||||||
v4 Right = V4Cross(Normal, v4{0, 1, 0, 0});
|
|
||||||
|
|
||||||
v4 FrontCenter = Center + (Normal * 25);
|
|
||||||
v4 BackCenter = Center - (Normal * 25);
|
|
||||||
|
|
||||||
r32 OuterRadiusSquared = 1000000;
|
|
||||||
r32 InnerRadiusSquared = 0;
|
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 Position = Leds->Positions[LedIndex];
|
|
||||||
|
|
||||||
v4 ToFront = Position + FrontCenter;
|
|
||||||
v4 ToBack = Position + BackCenter;
|
|
||||||
|
|
||||||
r32 ToFrontDotNormal = V4Dot(ToFront, Normal);
|
|
||||||
r32 ToBackDotNormal = V4Dot(ToBack, Normal);
|
|
||||||
|
|
||||||
ToFrontDotNormal = Clamp01(ToFrontDotNormal * 1000);
|
|
||||||
ToBackDotNormal = Clamp01(ToBackDotNormal * 1000);
|
|
||||||
|
|
||||||
r32 SqDistToCenter = V4MagSquared(Position);
|
|
||||||
if (SqDistToCenter < OuterRadiusSquared && SqDistToCenter > InnerRadiusSquared)
|
|
||||||
{
|
|
||||||
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
|
||||||
{
|
|
||||||
Leds->Colors[LedIndex] = Color;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Leds->Colors[LedIndex] = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Leds->Colors[LedIndex] = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
TestPatternThree(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
v4 GreenCenter = v4{0, 0, 150, 1};
|
|
||||||
r32 GreenRadius = Abs(SinR32(Time)) * 200;
|
|
||||||
|
|
||||||
v4 TealCenter = v4{0, 0, 150, 1};
|
|
||||||
r32 TealRadius = Abs(SinR32(Time + 1.5)) * 200;
|
|
||||||
|
|
||||||
r32 FadeDist = 35;
|
|
||||||
|
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 LedPosition = Leds->Positions[LedIndex];
|
|
||||||
u8 Red = 0;
|
|
||||||
u8 Green = 0;
|
|
||||||
u8 Blue = 0;
|
|
||||||
|
|
||||||
r32 GreenDist = Abs(V4Mag(LedPosition - GreenCenter) - GreenRadius);
|
|
||||||
r32 GreenBrightness = Clamp(0.f, FadeDist - Abs(GreenDist), FadeDist);
|
|
||||||
Green = (u8)(GreenBrightness * 255);
|
|
||||||
|
|
||||||
r32 TealDist = Abs(V4Mag(LedPosition - TealCenter) - TealRadius);
|
|
||||||
r32 TealBrightness = Clamp(0.f, FadeDist - Abs(TealDist), FadeDist);
|
|
||||||
Red = (u8)(TealBrightness * 255);
|
|
||||||
Blue = (u8)(TealBrightness * 255);
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex].R = Red;
|
|
||||||
Leds->Colors[LedIndex].B = Green;
|
|
||||||
Leds->Colors[LedIndex].G = Green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v4 RGBToHSV(v4 In)
|
v4 RGBToHSV(v4 In)
|
||||||
{
|
{
|
||||||
v4 Result = {};
|
v4 Result = {};
|
||||||
|
@ -697,6 +494,22 @@ while (Hue > 360.0f) { Hue -= 360.0f; }
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_AltBloomMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
v3 SphereCenter = Assembly.Center - v3{0, -150, 0};
|
||||||
|
r32 SphereRadius = Time;
|
||||||
|
r32 SphereBrightness = 1;
|
||||||
|
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
{
|
||||||
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
r32 Sphere = SDF_SphereNormalized(P, SphereCenter, SphereRadius);
|
||||||
|
Sphere = Clamp01(-Sphere);
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(WhiteV4 * Sphere);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_HueShift(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_HueShift(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
|
@ -728,7 +541,7 @@ Pattern_HueShift(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r3
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_HueFade(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Rainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
r32 HueBase = ModR32(Time * 50, 360);
|
r32 HueBase = ModR32(Time * 50, 360);
|
||||||
|
|
||||||
|
@ -748,49 +561,7 @@ Pattern_HueFade(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_AllGreen(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_RadialRainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
|
||||||
{
|
|
||||||
u32 I = LedIndex + 1;
|
|
||||||
Leds->Colors[LedIndex] = {0, 255, 0};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal r32
|
|
||||||
PatternHash(r32 Seed)
|
|
||||||
{
|
|
||||||
return FractR32(Seed * 17.0 * FractR32(Seed * 0.3183099));
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_Spots(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
pixel ColorA = { 0, 255, 255 };
|
|
||||||
pixel ColorB = { 255, 0, 255 };
|
|
||||||
|
|
||||||
r32 Speed = .5f;
|
|
||||||
Time *= Speed;
|
|
||||||
r32 ScaleA = 2 * SinR32(Time / 5);
|
|
||||||
r32 ScaleB = 2.4f * CosR32(Time / 2.5f);
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 P = Leds->Positions[LedIndex];
|
|
||||||
r32 V = P.y;
|
|
||||||
r32 Noise = .3f * PatternHash(V);
|
|
||||||
r32 ThetaY = (Leds->Positions[LedIndex].y / 10) + Time + Noise;
|
|
||||||
r32 ThetaX = (Leds->Positions[LedIndex].x / 13) + Time + Noise;
|
|
||||||
r32 Fade = (ScaleA * SinR32(ThetaY)) + (ScaleB * CosR32(3 * ThetaX));
|
|
||||||
Fade = RemapClampedR32(Fade, -1, 1, 0, 1);
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex].R = (u8)LerpR32(Fade, ColorA.R, ColorB.R);
|
|
||||||
Leds->Colors[LedIndex].G = (u8)LerpR32(Fade, ColorA.G, ColorB.G);
|
|
||||||
Leds->Colors[LedIndex].B = (u8)LerpR32(Fade, ColorA.B, ColorB.B);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_LighthouseRainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
{
|
||||||
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
@ -803,196 +574,16 @@ Pattern_LighthouseRainbow(led_buffer* Leds, led_buffer_range Range, assembly Ass
|
||||||
|
|
||||||
r32 Angle = V2Dot(RefVector, Vector);
|
r32 Angle = V2Dot(RefVector, Vector);
|
||||||
|
|
||||||
v4 HSV = { (Angle * 30) + (Time * 10) + Leds->Positions[LedIndex].y, 1, 1, 1 };
|
v4 HSV = { (Angle * 30) + (Time * 10), 1, 1, 1 };
|
||||||
v4 RGB = HSVToRGB(HSV);
|
v4 RGB = HSVToRGB(HSV);
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_SmoothGrowRainbow(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
r32 FillCycleTime = ModR32(Time, 7.0f) / 7.0f;
|
|
||||||
r32 ColorCycleTime = ModR32(Time, 21.0f) / 21.0f;
|
|
||||||
|
|
||||||
v4 HSV = { 0, 1, 1, 1 };
|
|
||||||
for (u32 s = 0; s < Assembly.StripCount; s++)
|
|
||||||
{
|
|
||||||
v2_strip Strip = Assembly.Strips[s];
|
|
||||||
|
|
||||||
v4 RGB0 = HSVToRGB(HSV);
|
|
||||||
for (u32 l = 0; l < Strip.LedCount; l++)
|
|
||||||
{
|
|
||||||
u32 LedIndex = Strip.LedLUT[l];
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB0);
|
|
||||||
}
|
|
||||||
|
|
||||||
HSV.x += 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_GrowAndFade(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
r32 PercentCycle = ModR32(Time, 10) / 10;
|
|
||||||
v4 HSV = { PercentCycle * 360, 1, 1, 1 };
|
|
||||||
v4 RGB = HSVToRGB(HSV);
|
|
||||||
|
|
||||||
r32 RefHeight = -100 + (Smoothstep(PercentCycle * 1.4f) * 400);
|
|
||||||
r32 RefBrightness = 1.0f - Smoothstep(PercentCycle);
|
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 P = Leds->Positions[LedIndex];
|
|
||||||
|
|
||||||
v4 RgbFaded = v4{};
|
|
||||||
if (P.y < RefHeight)
|
|
||||||
{
|
|
||||||
RgbFaded = RGB * RefBrightness;
|
|
||||||
}
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RgbFaded);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_ColorToWhite(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
r32 FadeBottomBase = 50;
|
|
||||||
r32 FadeTop = 125;
|
|
||||||
|
|
||||||
for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
|
|
||||||
{
|
|
||||||
v2_strip Strip = Assembly.Strips[StripIndex];
|
|
||||||
|
|
||||||
r32 FlowerSpread = .8f;
|
|
||||||
r32 FlowerOffset = 0;
|
|
||||||
if (AssemblyStrip_HasTagValueSLOW(Strip, "flower", "center"))
|
|
||||||
{
|
|
||||||
FlowerOffset = 1;
|
|
||||||
}
|
|
||||||
else if (AssemblyStrip_HasTagValueSLOW(Strip, "flower", "right"))
|
|
||||||
{
|
|
||||||
FlowerOffset = 2;
|
|
||||||
}
|
|
||||||
FlowerOffset *= FlowerSpread;
|
|
||||||
|
|
||||||
r32 PercentCycle = ModR32(Time + FlowerOffset, 10) / 10;
|
|
||||||
|
|
||||||
r32 FadeBottom = FadeBottomBase + RemapR32(SinR32((PercentCycle * 4) * TauR32), -1, 1, -50, 50);
|
|
||||||
|
|
||||||
v4 TopRGB = WhiteV4;
|
|
||||||
pixel TopColor = V4ToRGBPixel(TopRGB);
|
|
||||||
|
|
||||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
|
||||||
{
|
|
||||||
u32 LedIndex = Strip.LedLUT[i];
|
|
||||||
v4 P = Leds->Positions[LedIndex];
|
|
||||||
|
|
||||||
pixel FinalColor = {};
|
|
||||||
if (P.y > FadeTop)
|
|
||||||
{
|
|
||||||
FinalColor = TopColor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r32 B = RemapR32(SinR32((P.y / 15.f) + (PercentCycle * TauR32)), -1, 1, .5f, 1.f);
|
|
||||||
r32 HNoise = RemapR32(SinR32((P.y / 31.f) + (PercentCycle * TauR32)), -1, 1, -32.f, 32.f);
|
|
||||||
v4 BottomRGB = HSVToRGB(v4{ (PercentCycle * 360) + HNoise, 1, B, 1 });
|
|
||||||
|
|
||||||
if (P.y < FadeBottom)
|
|
||||||
{
|
|
||||||
FinalColor = V4ToRGBPixel(BottomRGB);
|
|
||||||
}
|
|
||||||
else if (P.y >= FadeBottom && P.y <= FadeTop)
|
|
||||||
{
|
|
||||||
r32 FadePct = RemapR32(P.y, FadeBottom, FadeTop, 0, 1);
|
|
||||||
v4 MixRGB = V4Lerp(FadePct, BottomRGB, TopRGB);
|
|
||||||
FinalColor = V4ToRGBPixel(MixRGB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = FinalColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_FlowerColorToWhite(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
|
||||||
{
|
|
||||||
r32 FadeBottomBase = 50;
|
|
||||||
r32 FadeTop = 125;
|
|
||||||
|
|
||||||
for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
|
|
||||||
{
|
|
||||||
v2_strip Strip = Assembly.Strips[StripIndex];
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// All flowers same flower type
|
|
||||||
pixel* Colors = &FlowerAColors[0];
|
|
||||||
r32 FlowerSpread = .8f;
|
|
||||||
r32 FlowerOffset = 0;
|
|
||||||
if (AssemblyStrip_HasTagValueSLOW(Strip, "flower", "center"))
|
|
||||||
{
|
|
||||||
FlowerOffset = 1;
|
|
||||||
}
|
|
||||||
else if (AssemblyStrip_HasTagValueSLOW(Strip, "flower", "right"))
|
|
||||||
{
|
|
||||||
FlowerOffset = 2;
|
|
||||||
}
|
|
||||||
FlowerOffset *= FlowerSpread;
|
|
||||||
#else
|
|
||||||
// Each flower different
|
|
||||||
v4* Colors = &FlowerAColors[0];
|
|
||||||
r32 FlowerOffset = 0;
|
|
||||||
if (AssemblyStrip_HasTagValueSLOW(Strip, "flower", "center"))
|
|
||||||
{
|
|
||||||
Colors = &FlowerBColors[0];
|
|
||||||
}
|
|
||||||
else if (AssemblyStrip_HasTagValueSLOW(Strip, "flower", "right"))
|
|
||||||
{
|
|
||||||
Colors = &FlowerCColors[0];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
r32 PercentCycle = ModR32(Time + FlowerOffset, 10) / 10;
|
|
||||||
|
|
||||||
r32 FadeBottom = FadeBottomBase + RemapR32(SinR32((PercentCycle * 4) * TauR32), -1, 1, -50, 50);
|
|
||||||
|
|
||||||
for (u32 i = 0; i < Strip.LedCount; i++)
|
|
||||||
{
|
|
||||||
u32 LedIndex = Strip.LedLUT[i];
|
|
||||||
v4 P = Leds->Positions[LedIndex];
|
|
||||||
|
|
||||||
v4 FinalColor = {};
|
|
||||||
r32 B = RemapR32(SinR32((P.y / 15.f) + (PercentCycle * TauR32)), -1, 1, .5f, 1.f);
|
|
||||||
r32 HNoise = RemapR32(SinR32((P.y / 31.f) + (PercentCycle * TauR32)), -1, 1, 0.f, 1.f);
|
|
||||||
|
|
||||||
v4 BottomColor = GetColor(Colors, FLOWER_COLORS_COUNT, (PercentCycle + HNoise) / 2);
|
|
||||||
|
|
||||||
FinalColor = BottomColor;
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(FinalColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r32 TLastFrame = 0;
|
|
||||||
v4* FAC = &FlowerAColors[0];
|
|
||||||
v4* FBC = &FlowerBColors[0];
|
|
||||||
v4* FCC = &FlowerCColors[0];
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_BasicFlowers(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_BasicFlowers(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
if (TLastFrame > Time)
|
|
||||||
{
|
|
||||||
v4 * Temp = FAC;
|
|
||||||
FAC = FBC;
|
|
||||||
FBC = FCC;
|
|
||||||
FCC = Temp;
|
|
||||||
}
|
|
||||||
TLastFrame = Time;
|
|
||||||
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
||||||
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
||||||
|
@ -1032,30 +623,58 @@ Pattern_Wavy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Ti
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||||
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
||||||
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
||||||
|
v4 C2 = HSVToRGB({Hue.Hue2, 1, 1, 1});
|
||||||
|
|
||||||
|
r32 Top = 120 + (SinR32(Time) * 10);
|
||||||
|
r32 Mid = 70 + (CosR32(Time * 2.13) * 20);
|
||||||
|
r32 Bot = 0;
|
||||||
|
|
||||||
|
r32 TopD = Top - Mid;
|
||||||
|
r32 BotD = Mid - Bot;
|
||||||
|
r32 MidD = Min(TopD, BotD);
|
||||||
|
|
||||||
|
//r32 MaxFadeDistance = 10;
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
|
||||||
v3 Pp = P.xyz;
|
r32 PercentTop = Clamp01(1.0f - ((Top - P.y) / TopD));
|
||||||
|
|
||||||
r32 Noise = Fbm3D((Pp / 1000) + (v3{Time, -Time, Time} * 0.01f));
|
r32 PercentMid = Clamp01(1.0f - Abs(P.y - Mid) / MidD);
|
||||||
Noise = RemapR32(Noise, -1, 1, 0, 1);
|
r32 N = Noise3D((P / 17) + v3{Time, -Time, 0});
|
||||||
Noise = Smoothstep(Noise, 0, 1);
|
N = Clamp01(N) * 2;
|
||||||
u8 NV = (u8)(Noise * 255);
|
N = Smoothstep(N);
|
||||||
|
N *= N;
|
||||||
|
N = Smoothstep(N);
|
||||||
|
N *= 1.0f - PowR32(1.0f - PercentMid, 4);
|
||||||
|
PercentMid = Clamp01(PercentMid + N);
|
||||||
|
|
||||||
v3 BSeed = v3{P.z, P.x, P.y};
|
r32 PercentBot = Clamp01(1.0f - ((P.y - Bot) / BotD));
|
||||||
r32 BNoise = 1.0f; //Fbm3D(BSeed / 50);
|
|
||||||
|
|
||||||
v4 C = V4Lerp(BNoise, C0, C1);
|
v4 TopC = (C0 * PercentTop);
|
||||||
C = C * BNoise;
|
v4 MidC = (C1 * PercentMid);
|
||||||
|
v4 BotC = (C2 * PercentBot);
|
||||||
|
|
||||||
//Leds->Colors[LedIndex] = V4ToRGBPixel(v4{Noise, Noise, Noise, 1});
|
v4 C = {};
|
||||||
|
if (PercentTop > PercentMid && PercentTop > PercentBot)
|
||||||
|
{
|
||||||
|
C = C0;
|
||||||
|
}
|
||||||
|
else if (PercentMid > PercentBot)
|
||||||
|
{
|
||||||
|
C = C1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
C = C2;
|
||||||
|
}
|
||||||
|
|
||||||
|
r32 ScaleFactor = PercentTop + PercentMid + PercentBot;
|
||||||
|
C = (TopC + MidC + BotC) / ScaleFactor;
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
//Leds->Colors[LedIndex] = pixel{NV, NV, NV};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,7 +684,7 @@ Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % BL_FLOWER_COUNT];
|
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||||
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
||||||
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
||||||
|
|
||||||
|
@ -1086,70 +705,71 @@ Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
|
||||||
NoiseB = Smoothstep(NoiseB);
|
NoiseB = Smoothstep(NoiseB);
|
||||||
v4 CB = C1 * NoiseB;
|
v4 CB = C1 * NoiseB;
|
||||||
|
|
||||||
v4 C = CA + CB;
|
v4 C = (C0 * NoiseA) + (C1 * NoiseB);
|
||||||
|
C /= (NoiseA + NoiseB);
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Leafy_BandSDF(v3 P, gs_random_series* Random, r32 Time)
|
||||||
|
{
|
||||||
|
r32 MinBandThickness = 5;
|
||||||
|
r32 MaxBandThickness = 10;
|
||||||
|
r32 MaxTransitionPeriod = 120.0f;
|
||||||
|
|
||||||
|
r32 BandTransitionPeriod = NextRandomUnilateral(Random) * MaxTransitionPeriod;
|
||||||
|
r32 BandTransitionBias = (1 - Clamp(0, (Time / (MaxTransitionPeriod / 2)), 0.7f)); // approaches 0.5 over time
|
||||||
|
BandTransitionPeriod *= BandTransitionBias;
|
||||||
|
|
||||||
|
r32 BandPercent = ModR32(Time, BandTransitionPeriod) / BandTransitionPeriod;
|
||||||
|
BandPercent = Smoothstep(BandPercent);
|
||||||
|
r32 BandY = -150 + (BandPercent * 290);
|
||||||
|
|
||||||
|
r32 ThickRand = NextRandomUnilateral(Random);
|
||||||
|
// 1 - 4((ThickRand - .5)^2) - distribution curve
|
||||||
|
ThickRand = 1.0f - ((4 * PowR32(ThickRand, 2)) - (4 * ThickRand) + 1);
|
||||||
|
r32 BandThickness = MinBandThickness + (ThickRand * (MaxBandThickness - MinBandThickness));
|
||||||
|
|
||||||
|
// BandBrightness = 1 - ((2x - 1) ^ 8) where x is BandPercent
|
||||||
|
r32 BandBrightness = 1.0f - PowR32((2 * BandPercent) - 1, 8);
|
||||||
|
BandBrightness *= RemapR32(NextRandomUnilateral(Random), 0, 1, .25f, 1);
|
||||||
|
r32 Result = 1 - Clamp01(Abs(P.y - BandY) / BandThickness);
|
||||||
|
Result *= BandBrightness;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_Leafy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_Leafy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||||
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
||||||
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
||||||
|
v4 C2 = HSVToRGB({Hue.Hue2, 1, 1, 1});
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
|
||||||
#if 0
|
|
||||||
r32 RefPos = P.y + Noise2D(v2{P.x, P.z} * 10);
|
|
||||||
|
|
||||||
v4 C = {};
|
v4 C = {};
|
||||||
r32 B = 0;
|
r32 B = 0;
|
||||||
|
|
||||||
r32 BandWidth = 5;
|
// NOTE(PS): initializing the Random seed inside the Led Loop
|
||||||
r32 TransitionPeriod = 30.0f;
|
// so that the bands are consistently calculated for each led
|
||||||
u32 BandCount = 10;
|
// ie. each time you calculate a band, the random numbers requested
|
||||||
|
// will always be the same
|
||||||
|
gs_random_series Random = InitRandomSeries(24601);
|
||||||
|
u32 BandCount = 25;
|
||||||
for (u32 Band = 0; Band < BandCount; Band++)
|
for (u32 Band = 0; Band < BandCount; Band++)
|
||||||
{
|
{
|
||||||
r32 BandSeed = Hash1((r32)Band);
|
B += Leafy_BandSDF(P.xyz, &Random, Time);
|
||||||
r32 BandSeedPos = RemapR32(BandSeed, -1, 1, 0, 1);
|
|
||||||
r32 BandDelay = BandSeedPos * TransitionPeriod;
|
|
||||||
r32 BandTransitionPeriod = RemapR32(Hash1((r32)Band * 3.413f), -1, 1, 0, 1) * TransitionPeriod;
|
|
||||||
r32 BandOffset = Time + BandDelay;
|
|
||||||
r32 BandPercent = ModR32(BandOffset, BandTransitionPeriod) / BandTransitionPeriod;
|
|
||||||
r32 BandSmoothed = Smoothstep(BandPercent, 0, 1);
|
|
||||||
|
|
||||||
r32 BandHeight = -125 + BandPercent * 250;
|
|
||||||
|
|
||||||
r32 BandDist = Abs(RefPos - BandHeight);
|
|
||||||
|
|
||||||
B += Max(0, (BandWidth + BandSeed * 2.5) - BandDist);
|
|
||||||
}
|
}
|
||||||
B = Clamp(0, B, 1);
|
B = Clamp01(B);
|
||||||
|
|
||||||
r32 BandCP = (P.y + 100) / 200;
|
C = WhiteV4 * B;
|
||||||
BandCP = 0.8f;
|
|
||||||
v4 BandC = GetColor(&FlowerBColors[0], FLOWER_COLORS_COUNT, BandCP);
|
|
||||||
|
|
||||||
v4 GradientC = GetColor(&FlowerBColors[0], FLOWER_COLORS_COUNT, 0);
|
|
||||||
r32 GradientB = RemapR32(P.y, 200, 0, 1, 0);
|
|
||||||
GradientB = Clamp(0, GradientB, 1);
|
|
||||||
|
|
||||||
C = (GradientC * GradientB) + (BandC * B);
|
|
||||||
#endif
|
|
||||||
//v4 C = GetColor(&FlowerBColors[0], FLOWER_COLORS_COUNT, 0);
|
|
||||||
v4 C = v4{ 255, 100, 3 };
|
|
||||||
C /= 255.f;
|
|
||||||
//r32 B = Fbm3D(P.xyz / 200);
|
|
||||||
//C *= B;
|
|
||||||
if (P.y < 75) {
|
|
||||||
C = v4{ 139 / 255.f, 69 / 255.f, 19 / 255.f, 1.0f} * .25f;
|
|
||||||
}
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1159,33 +779,44 @@ Pattern_LeafyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly,
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
|
||||||
|
phrase_hue Hue = BlumenLumen_GetCurrentHue(BLState, Assembly);
|
||||||
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
v4 C0 = HSVToRGB({Hue.Hue0, 1, 1, 1});
|
||||||
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
v4 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
|
||||||
|
v4 C2 = HSVToRGB({Hue.Hue2, 1, 1, 1});
|
||||||
|
|
||||||
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
{
|
{
|
||||||
v4 P = Leds->Positions[LedIndex];
|
v4 P = Leds->Positions[LedIndex];
|
||||||
r32 LedRange = 300.0f;
|
|
||||||
r32 ScaleFactor = 1.0f / LedRange;
|
|
||||||
v3 Pp = P.xyz + v3{150, 100, 0};
|
v3 Pp = P.xyz + v3{150, 100, 0};
|
||||||
|
|
||||||
r32 NoiseA = Fbm3D((Pp / 35), Time * 0.5f);
|
r32 NoiseA = Fbm3D((Pp / 18), Time * 0.25f);
|
||||||
//NoiseA = PowR32(NoiseA, 3);
|
|
||||||
NoiseA = Smoothstep(NoiseA);
|
NoiseA = Smoothstep(NoiseA);
|
||||||
v4 CA = C0 * NoiseA;
|
|
||||||
|
|
||||||
r32 NoiseB = Noise3D((Pp / 35) + v3{0, 0, Time * 5});
|
r32 NoiseB = Noise3D((Pp / 35) + v3{0, 0, Time * 0.5f});
|
||||||
NoiseB = PowR32(NoiseB, 3);
|
NoiseB = PowR32(NoiseB, 3);
|
||||||
NoiseB = Smoothstep(NoiseB);
|
NoiseB = Smoothstep(NoiseB);
|
||||||
v4 CB = C1;
|
|
||||||
|
|
||||||
v4 C = V4Lerp(NoiseB, CA, CB);
|
r32 NoiseC = Noise3D((Pp / 25) + v3{0, 0, Time * 4});
|
||||||
|
r32 CPresence = SinR32((P.y / 50) - Time) + (0.8f * SinR32((P.y / 25) - (Time * 5.0f)));
|
||||||
|
CPresence = RemapR32(CPresence, -1.8, 1.8, 0, 1);
|
||||||
|
CPresence = PowR32(CPresence, 4);
|
||||||
|
NoiseC *= CPresence;
|
||||||
|
|
||||||
|
v4 C = (C0 * NoiseA * 0.5f) + (C1 * NoiseB) + (C2 * NoiseC);
|
||||||
|
C *= 1.0f / (NoiseA + NoiseB + NoiseC);
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Pattern_WavyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
Pattern_WavyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_VerticalLines(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
blumen_lumen_state* BLState = (blumen_lumen_state*)UserData;
|
||||||
|
@ -1194,22 +825,11 @@ Pattern_WavyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly,
|
||||||
r32 LightSpeedMin = 1;
|
r32 LightSpeedMin = 1;
|
||||||
r32 LightSpeedMax = 5;
|
r32 LightSpeedMax = 5;
|
||||||
|
|
||||||
#if 0
|
|
||||||
r32 LightHueMin = (ModR32(Time, 10) / 10) * 360;
|
|
||||||
r32 LightHueMax = ModR32((LightHueMin + 45), 360) ;
|
|
||||||
#else
|
|
||||||
r32 CenterHue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3].Hue0;
|
|
||||||
r32 LightHueMin = ModR32(CenterHue + 30, 360);;
|
|
||||||
r32 LightHueMax = ModR32(CenterHue - 30, 360) ;
|
|
||||||
#endif
|
|
||||||
s32 LightTailLength = 10;
|
s32 LightTailLength = 10;
|
||||||
for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
|
for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
|
||||||
{
|
{
|
||||||
v2_strip Strip = Assembly.Strips[StripIndex];
|
v2_strip Strip = Assembly.Strips[StripIndex];
|
||||||
|
|
||||||
r32 LightHue = LerpR32(NextRandomUnilateral(&Random),
|
|
||||||
LightHueMin,
|
|
||||||
LightHueMax);
|
|
||||||
r32 LightStartHeight = NextRandomUnilateral(&Random);
|
r32 LightStartHeight = NextRandomUnilateral(&Random);
|
||||||
r32 LightSpeed = LerpR32(NextRandomUnilateral(&Random),
|
r32 LightSpeed = LerpR32(NextRandomUnilateral(&Random),
|
||||||
LightSpeedMin,
|
LightSpeedMin,
|
||||||
|
@ -1224,11 +844,99 @@ Pattern_WavyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly,
|
||||||
|
|
||||||
u32 LedIndex = Strip.LedLUT[StripLedIndex];
|
u32 LedIndex = Strip.LedLUT[StripLedIndex];
|
||||||
r32 PctTail = ((r32)i / (r32)LightTailLength);
|
r32 PctTail = ((r32)i / (r32)LightTailLength);
|
||||||
v4 C = HSVToRGB(v4{LightHue, 1, 1, 1}) * PctTail;
|
v4 C = WhiteV4 * PctTail;
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_Rotary(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
gs_random_series Random = InitRandomSeries(24601);
|
||||||
|
|
||||||
|
#define SphereCount 32
|
||||||
|
v3 SphereCenter[SphereCount];
|
||||||
|
|
||||||
|
r32 MaxHeightOffset = 150;
|
||||||
|
r32 MaxSpeed = 10;
|
||||||
|
r32 SphereRadius = 2.0f;
|
||||||
|
for (u32 i = 0; i < SphereCount; i++)
|
||||||
|
{
|
||||||
|
r32 SphereSeedA = NextRandomBilateral(&Random);
|
||||||
|
r32 SphereSeedB = NextRandomBilateral(&Random);
|
||||||
|
r32 SphereSpeed = NextRandomUnilateral(&Random) * MaxSpeed;
|
||||||
|
|
||||||
|
r32 SphereTime = Time + SphereSpeed;
|
||||||
|
r32 HeightOffset = SphereTime + (SphereSeedA * MaxHeightOffset);
|
||||||
|
r32 RotationOffset = SphereTime + SphereSeedB * TauR32;
|
||||||
|
r32 SphereRotationDir = NextRandomBilateral(&Random) < 0 ? -1 : 1;
|
||||||
|
v3 SpherePosOffset = v3{
|
||||||
|
SinR32(RotationOffset * SphereRotationDir) * (SphereRadius * 2),
|
||||||
|
HeightOffset,
|
||||||
|
CosR32(RotationOffset * SphereRotationDir) * (SphereRadius * 2)
|
||||||
|
};
|
||||||
|
SphereCenter[i] = Assembly.Center + SpherePosOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
{
|
||||||
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
|
||||||
|
r32 Dist = 10000000;
|
||||||
|
for (u32 i = 0; i < SphereCount; i++)
|
||||||
|
{
|
||||||
|
r32 SphereSDF = Abs(SDF_Sphere(P, SphereCenter[i], SphereRadius));
|
||||||
|
SphereSDF = SphereSDF / SphereRadius;
|
||||||
|
Dist = Min(Dist, SphereSDF);
|
||||||
|
}
|
||||||
|
|
||||||
|
v4 C = BlackV4;
|
||||||
|
if (Dist <= 1)
|
||||||
|
{
|
||||||
|
r32 Brightness = Clamp01(SphereRadius - Dist);
|
||||||
|
C = WhiteV4 * Brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_AllOnMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
pixel White = V4ToRGBPixel(WhiteV4);
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
{
|
||||||
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
Leds->Colors[LedIndex] = White;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_BulbMask(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
r32 Top = 141;
|
||||||
|
r32 BulbRange = 50;
|
||||||
|
|
||||||
|
pixel White = V4ToRGBPixel(WhiteV4);
|
||||||
|
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
|
||||||
|
{
|
||||||
|
v3 P = Leds->Positions[LedIndex].xyz;
|
||||||
|
|
||||||
|
r32 BulbSDF = 1 - Clamp01(((Top - P.y) - BulbRange) / BulbRange);
|
||||||
|
r32 N = Noise3D((P / 17) + v3{Time, -Time, 0});
|
||||||
|
N = Clamp01(N) * 2;
|
||||||
|
N = Smoothstep(N);
|
||||||
|
N *= N;
|
||||||
|
N = Smoothstep(N);
|
||||||
|
N *= 1.0f - PowR32(1.0f - BulbSDF, 4);
|
||||||
|
BulbSDF += N;
|
||||||
|
BulbSDF = Clamp01(BulbSDF);
|
||||||
|
v4 C = WhiteV4 * BulbSDF;
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define BLUMEN_PATTERNS_H
|
#define BLUMEN_PATTERNS_H
|
||||||
#endif // BLUMEN_PATTERNS_H
|
#endif // BLUMEN_PATTERNS_H
|
|
@ -430,14 +430,15 @@ Win32_SendAddressedDataBuffer_Job(gs_thread_context Context, gs_data Arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool
|
internal bool
|
||||||
ReloadAndLinkDLL(win32_dll_refresh* DLL, context* Context, gs_work_queue* WorkQueue, bool ShouldError)
|
ReloadAndLinkDLL(win32_dll_refresh* DLL, context* Context, gs_work_queue* WorkQueue, bool ShouldError, bool AppReady)
|
||||||
{
|
{
|
||||||
bool Success = false;
|
bool Success = false;
|
||||||
if (HotLoadDLL(DLL))
|
if (HotLoadDLL(DLL))
|
||||||
{
|
{
|
||||||
SetApplicationLinks(Context, *DLL, WorkQueue);
|
SetApplicationLinks(Context, *DLL, WorkQueue);
|
||||||
Context->ReloadStaticData(*Context, GlobalDebugServices);
|
Context->ReloadStaticData(*Context, GlobalDebugServices, AppReady);
|
||||||
Success = true;
|
Success = true;
|
||||||
|
OutputDebugStringA("Reloaded DLL\n");
|
||||||
}
|
}
|
||||||
else if(ShouldError)
|
else if(ShouldError)
|
||||||
{
|
{
|
||||||
|
@ -609,6 +610,20 @@ WinMain (
|
||||||
|
|
||||||
if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1;
|
if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1;
|
||||||
|
|
||||||
|
context Context = {};
|
||||||
|
Context.ThreadContext = ThreadContext;
|
||||||
|
Context.MemorySize = MB(64);
|
||||||
|
Context.MemoryBase = (u8*)Win32Alloc(Context.MemorySize, 0);
|
||||||
|
|
||||||
|
gs_const_string Args = ConstString((char*)CmdLineArgs);
|
||||||
|
if (StringsEqual(Args, ConstString("-headless")))
|
||||||
|
{
|
||||||
|
OutputDebugStringA("Running Headless\n");
|
||||||
|
Context.Headless = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Context.Headless)
|
||||||
|
{
|
||||||
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
||||||
Win32UpdateWindowDimension(&MainWindow);
|
Win32UpdateWindowDimension(&MainWindow);
|
||||||
|
|
||||||
|
@ -617,11 +632,7 @@ WinMain (
|
||||||
OpenGLWindowInfo.AlphaBits = 8;
|
OpenGLWindowInfo.AlphaBits = 8;
|
||||||
OpenGLWindowInfo.DepthBits = 0;
|
OpenGLWindowInfo.DepthBits = 0;
|
||||||
CreateOpenGLWindowContext(OpenGLWindowInfo, &MainWindow);
|
CreateOpenGLWindowContext(OpenGLWindowInfo, &MainWindow);
|
||||||
|
}
|
||||||
context Context = {};
|
|
||||||
Context.ThreadContext = ThreadContext;
|
|
||||||
Context.MemorySize = MB(64);
|
|
||||||
Context.MemoryBase = (u8*)Win32Alloc(Context.MemorySize, 0);
|
|
||||||
|
|
||||||
gs_memory_arena PlatformPermanent = CreateMemoryArena(Context.ThreadContext.Allocator, "Platform Memory");
|
gs_memory_arena PlatformPermanent = CreateMemoryArena(Context.ThreadContext.Allocator, "Platform Memory");
|
||||||
|
|
||||||
|
@ -657,7 +668,7 @@ WinMain (
|
||||||
*Context.SocketManager = CreatePlatformSocketManager(Win32ConnectSocket, Win32CloseSocket, Win32SocketQueryStatus, Win32SocketPeek, Win32SocketReceive, Win32SocketSend);
|
*Context.SocketManager = CreatePlatformSocketManager(Win32ConnectSocket, Win32CloseSocket, Win32SocketQueryStatus, Win32SocketPeek, Win32SocketReceive, Win32SocketSend);
|
||||||
|
|
||||||
win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName);
|
win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName);
|
||||||
if (!ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, true)) { return -1; }
|
if (!ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, true, false)) { return -1; }
|
||||||
|
|
||||||
Mouse_Init();
|
Mouse_Init();
|
||||||
|
|
||||||
|
@ -708,12 +719,13 @@ WinMain (
|
||||||
|
|
||||||
ResetInputQueue(&InputQueue);
|
ResetInputQueue(&InputQueue);
|
||||||
|
|
||||||
ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false);
|
ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false, true);
|
||||||
|
|
||||||
AddressedDataBufferList_Clear(&OutputData);
|
AddressedDataBufferList_Clear(&OutputData);
|
||||||
|
|
||||||
|
if (!Context.Headless)
|
||||||
|
{
|
||||||
Mouse_Update(MainWindow, &Context);
|
Mouse_Update(MainWindow, &Context);
|
||||||
|
|
||||||
MSG Message;
|
MSG Message;
|
||||||
while (PeekMessageA(&Message, MainWindow.Handle, 0, 0, PM_REMOVE))
|
while (PeekMessageA(&Message, MainWindow.Handle, 0, 0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
|
@ -724,18 +736,17 @@ WinMain (
|
||||||
Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
|
||||||
RenderBuffer.ViewWidth = MainWindow.Width;
|
RenderBuffer.ViewWidth = MainWindow.Width;
|
||||||
RenderBuffer.ViewHeight = MainWindow.Height;
|
RenderBuffer.ViewHeight = MainWindow.Height;
|
||||||
Context.DeltaTime = LastFrameSecondsElapsed;
|
}
|
||||||
|
|
||||||
#if 0
|
Context.DeltaTime = LastFrameSecondsElapsed;
|
||||||
gs_string T = PushStringF(Context.ThreadContext.Transient, 256, "%f\n", Context.DeltaTime);
|
Context.TotalTime += (r64)Context.DeltaTime;
|
||||||
NullTerminate(&T);
|
|
||||||
OutputDebugStringA(T.Str);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData);
|
Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData);
|
||||||
|
|
||||||
Win32_SendOutputData(ThreadContext, OutputData);
|
Win32_SendOutputData(ThreadContext, OutputData);
|
||||||
|
|
||||||
|
if (!Context.Headless)
|
||||||
|
{
|
||||||
RenderCommandBuffer(RenderBuffer);
|
RenderCommandBuffer(RenderBuffer);
|
||||||
ClearRenderBuffer(&RenderBuffer);
|
ClearRenderBuffer(&RenderBuffer);
|
||||||
|
|
||||||
|
@ -744,6 +755,7 @@ WinMain (
|
||||||
HDC DeviceContext = GetDC(MainWindow.Handle);
|
HDC DeviceContext = GetDC(MainWindow.Handle);
|
||||||
SwapBuffers(DeviceContext);
|
SwapBuffers(DeviceContext);
|
||||||
ReleaseDC(MainWindow.Handle, DeviceContext);
|
ReleaseDC(MainWindow.Handle, DeviceContext);
|
||||||
|
}
|
||||||
|
|
||||||
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
|
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
|
||||||
|
|
||||||
|
@ -767,8 +779,6 @@ WinMain (
|
||||||
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
|
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
|
||||||
|
|
||||||
Win32WorkQueue_Cleanup();
|
Win32WorkQueue_Cleanup();
|
||||||
//Win32_TestCode_SocketReading_Cleanup();
|
|
||||||
|
|
||||||
Win32SocketSystem_Cleanup();
|
Win32SocketSystem_Cleanup();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -194,28 +194,18 @@ BlumenLumen_LoadPatterns(app_state* State)
|
||||||
}
|
}
|
||||||
|
|
||||||
Patterns->Count = 0;
|
Patterns->Count = 0;
|
||||||
Patterns_PushPattern(Patterns, TestPatternOne, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, TestPatternTwo, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, TestPatternThree, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_AllGreen, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_HueShift, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_HueShift, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_HueFade, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_Rainbow, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Spots, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_LighthouseRainbow, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_SmoothGrowRainbow, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_GrowAndFade, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_ColorToWhite, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_Blue, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_Green, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_FlowerColors, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_FlowerColorToWhite, PATTERN_MULTITHREADED);
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_BasicFlowers, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_BasicFlowers, PATTERN_MULTITHREADED);
|
||||||
// 15
|
|
||||||
Patterns_PushPattern(Patterns, Pattern_Wavy, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_Wavy, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Patchy, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_Patchy, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_Leafy, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_Leafy, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_LeafyPatchy, PATTERN_MULTITHREADED);
|
Patterns_PushPattern(Patterns, Pattern_LeafyPatchy, PATTERN_MULTITHREADED);
|
||||||
Patterns_PushPattern(Patterns, Pattern_WavyPatchy, PATTERN_SINGLETHREADED);
|
Patterns_PushPattern(Patterns, Pattern_WavyPatchy, PATTERN_SINGLETHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_VerticalLines, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_Rotary, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_AllOnMask, PATTERN_MULTITHREADED);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_BulbMask, PATTERN_MULTITHREADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal gs_data
|
internal gs_data
|
||||||
|
@ -240,6 +230,8 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
BLState->MicListenJobData.IncomingMsgQueue = &BLState->IncomingMsgQueue;
|
BLState->MicListenJobData.IncomingMsgQueue = &BLState->IncomingMsgQueue;
|
||||||
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
|
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
|
||||||
|
|
||||||
|
BLState->PatternSpeed = GlobalAnimSpeed;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData);
|
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData);
|
||||||
#endif
|
#endif
|
||||||
|
@ -267,38 +259,6 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
&State->Permanent);
|
&State->Permanent);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{ // Animation PLAYGROUND
|
|
||||||
animation_desc Desc = {};
|
|
||||||
Desc.NameSize = 256;
|
|
||||||
Desc.LayersCount = 8;
|
|
||||||
Desc.BlocksCount = 8;
|
|
||||||
Desc.MinFrames = 0;
|
|
||||||
Desc.MaxFrames = SecondsToFrames(15, State->AnimationSystem);
|
|
||||||
|
|
||||||
animation_desc Desc0 = Desc;
|
|
||||||
Desc.Name = "test_anim_zero";
|
|
||||||
animation Anim0 = Animation_Create(Desc0, &State->AnimationSystem);
|
|
||||||
Animation_AddLayer(&Anim0, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
|
||||||
Animation_AddBlock(&Anim0, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(15), 0);
|
|
||||||
BLState->AnimHandles[0] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim0);
|
|
||||||
|
|
||||||
animation_desc Desc1 = Desc;
|
|
||||||
Desc1.Name = "test_anim_one";
|
|
||||||
animation Anim1 = Animation_Create(Desc1, &State->AnimationSystem);
|
|
||||||
Animation_AddLayer(&Anim1, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
|
||||||
Animation_AddBlock(&Anim1, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(12), 0);
|
|
||||||
BLState->AnimHandles[1] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim1);
|
|
||||||
|
|
||||||
animation_desc Desc2 = Desc;
|
|
||||||
Desc2.Name = "i_love_you";
|
|
||||||
animation Anim2 = Animation_Create(Desc2, &State->AnimationSystem);;
|
|
||||||
Animation_AddLayer(&Anim2, MakeString("Base Layer"), BlendMode_Overwrite, &State->AnimationSystem);
|
|
||||||
Animation_AddBlock(&Anim2, 0, Anim0.PlayableRange.Max, Patterns_IndexToHandle(20), 0);
|
|
||||||
BLState->AnimHandles[2] = AnimationArray_Push(&State->AnimationSystem.Animations, Anim2);
|
|
||||||
|
|
||||||
State->AnimationSystem.ActiveFadeGroup.From = BLState->AnimHandles[2];
|
|
||||||
} // End Animation Playground
|
|
||||||
#elif 0
|
|
||||||
animation_handle DemoPatternsAnim = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem,
|
animation_handle DemoPatternsAnim = AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem,
|
||||||
State->Patterns,
|
State->Patterns,
|
||||||
Context,
|
Context,
|
||||||
|
@ -307,6 +267,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
|
||||||
#else
|
#else
|
||||||
BLState->ModeAnimations[BlumenPattern_Standard] = LoadAllAnimationsInDir(AmbientPatternFolder, BLState, State, Context);
|
BLState->ModeAnimations[BlumenPattern_Standard] = LoadAllAnimationsInDir(AmbientPatternFolder, BLState, State, Context);
|
||||||
BLState->ModeAnimations[BlumenPattern_VoiceCommand] = LoadAllAnimationsInDir(VoicePatternFolder, BLState, State, Context);
|
BLState->ModeAnimations[BlumenPattern_VoiceCommand] = LoadAllAnimationsInDir(VoicePatternFolder, BLState, State, Context);
|
||||||
|
AnimationSystem_LoadAnimationFromFile(&State->AnimationSystem, State->Patterns, Context, ConstString("data/blumen_animations/anim_demo.foldanim"));
|
||||||
|
|
||||||
BlumenLumen_SetPatternMode(BlumenPattern_Standard, 5, &State->AnimationSystem, BLState);
|
BlumenLumen_SetPatternMode(BlumenPattern_Standard, 5, &State->AnimationSystem, BLState);
|
||||||
#endif
|
#endif
|
||||||
|
@ -402,6 +363,20 @@ BlumenLumen_CustomUpdate(gs_data UserData, app_state* State, context* Context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update next frames Hues
|
||||||
|
r32 AnimTime = AnimationSystem_GetCurrentTime(State->AnimationSystem);
|
||||||
|
AnimTime = (r32)Context->TotalTime;
|
||||||
|
r32 BaseTime = AnimTime * BLState->PatternSpeed;
|
||||||
|
|
||||||
|
r32 ColorSpeed = 1; //.001;
|
||||||
|
r32 ColorOscSpeed = .05 * ColorSpeed;
|
||||||
|
r32 ColorRelOscSpeed = 1 * ColorSpeed;;
|
||||||
|
r32 ColorOscillation = (SinR32(BaseTime * ColorOscSpeed) + 1) / 2;
|
||||||
|
r32 ColorRelationship = 30 + (((1 + SinR32(BaseTime * ColorRelOscSpeed)) / 2) * 300);
|
||||||
|
BLState->StandardPatternHues.Hue0 = ModR32(ColorOscillation * 360, 360);
|
||||||
|
BLState->StandardPatternHues.Hue1 = ModR32(BaseTime + ColorRelationship, 360);
|
||||||
|
BLState->StandardPatternHues.Hue2 = LerpR32(.3f, BLState->StandardPatternHues.Hue0, BLState->StandardPatternHues.Hue1);
|
||||||
|
|
||||||
// Transition back to standard mode after some time
|
// Transition back to standard mode after some time
|
||||||
if (BLState->PatternMode == BlumenPattern_VoiceCommand)
|
if (BLState->PatternMode == BlumenPattern_VoiceCommand)
|
||||||
{
|
{
|
||||||
|
|
|
@ -155,6 +155,7 @@ struct blumen_lumen_state
|
||||||
|
|
||||||
system_time LastSendTime;
|
system_time LastSendTime;
|
||||||
|
|
||||||
|
phrase_hue StandardPatternHues;
|
||||||
phrase_hue AssemblyColors[BL_FLOWER_COUNT];
|
phrase_hue AssemblyColors[BL_FLOWER_COUNT];
|
||||||
u32 LastAssemblyColorSet;
|
u32 LastAssemblyColorSet;
|
||||||
|
|
||||||
|
@ -172,6 +173,7 @@ struct blumen_lumen_state
|
||||||
phrase_hue_map PhraseHueMap;
|
phrase_hue_map PhraseHueMap;
|
||||||
system_time TimeLastSetToVoiceMode;
|
system_time TimeLastSetToVoiceMode;
|
||||||
|
|
||||||
|
r32 PatternSpeed;
|
||||||
// Debug
|
// Debug
|
||||||
motor_packet DEBUG_PendingMotorPacket;
|
motor_packet DEBUG_PendingMotorPacket;
|
||||||
bool DEBUG_IgnoreWeatherDimmingLeds;
|
bool DEBUG_IgnoreWeatherDimmingLeds;
|
||||||
|
@ -179,6 +181,26 @@ struct blumen_lumen_state
|
||||||
|
|
||||||
#include "message_queue.cpp"
|
#include "message_queue.cpp"
|
||||||
|
|
||||||
|
internal phrase_hue
|
||||||
|
BlumenLumen_GetCurrentHue(blumen_lumen_state* BLState, assembly Assembly)
|
||||||
|
{
|
||||||
|
phrase_hue Result = {};
|
||||||
|
|
||||||
|
switch (BLState->PatternMode)
|
||||||
|
{
|
||||||
|
case BlumenPattern_Standard:
|
||||||
|
{
|
||||||
|
Result = BLState->StandardPatternHues;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case BlumenPattern_VoiceCommand:
|
||||||
|
{
|
||||||
|
Result = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -126,4 +126,8 @@ r32 HighTemperatureBrightnessPercent = .25f;
|
||||||
// lower it for heat reasons?
|
// lower it for heat reasons?
|
||||||
r32 FullBrightnessPercent = 1.0f;
|
r32 FullBrightnessPercent = 1.0f;
|
||||||
|
|
||||||
|
// A global modifier so Joerg can just slow all the patterns right down
|
||||||
|
// XD
|
||||||
|
r32 GlobalAnimSpeed = 1.0f;
|
||||||
|
|
||||||
#endif //BLUMEN_LUMEN_SETTINGS_H
|
#endif //BLUMEN_LUMEN_SETTINGS_H
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* date = March 29th 2021 10:41 pm */
|
||||||
|
|
||||||
|
#ifndef SDF_H
|
||||||
|
#define SDF_H
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
SDF_Sphere(v3 Point, v3 Center, r32 Radius)
|
||||||
|
{
|
||||||
|
r32 Result = V3Mag(Point - Center) - Radius;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
SDF_SphereNormalized(v3 Point, v3 Center, r32 Radius)
|
||||||
|
{
|
||||||
|
r32 Result = SDF_Sphere(Point, Center, Radius) / Radius;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SDF_H
|
|
@ -106,8 +106,8 @@ BuildFlower(gs_string* OutputBuffer, flower_desc Desc)
|
||||||
#if 1
|
#if 1
|
||||||
// the bloom stem inner
|
// the bloom stem inner
|
||||||
loop_desc BloomStemInner = {};
|
loop_desc BloomStemInner = {};
|
||||||
BloomStemInner.CenterStart = v3{0, 1.4f, 0} + Desc.Pos;
|
BloomStemInner.CenterStart = v3{0, 1.4f, 0};
|
||||||
BloomStemInner.CenterEnd = v3{0, .9f, 0} + Desc.Pos;
|
BloomStemInner.CenterEnd = v3{0, .9f, 0};
|
||||||
BloomStemInner.Radius = .05f;
|
BloomStemInner.Radius = .05f;
|
||||||
BloomStemInner.SegmentsCount = 6;
|
BloomStemInner.SegmentsCount = 6;
|
||||||
BloomStemInner.SubsegmentsCount = 3;
|
BloomStemInner.SubsegmentsCount = 3;
|
||||||
|
@ -120,8 +120,8 @@ BuildFlower(gs_string* OutputBuffer, flower_desc Desc)
|
||||||
|
|
||||||
// the bloom stem outer
|
// the bloom stem outer
|
||||||
loop_desc BloomStemOuter = {};
|
loop_desc BloomStemOuter = {};
|
||||||
BloomStemOuter.CenterStart = v3{0, .5f, 0} + Desc.Pos;
|
BloomStemOuter.CenterStart = v3{0, .5f, 0};
|
||||||
BloomStemOuter.CenterEnd = v3{0, .9f, 0} + Desc.Pos;
|
BloomStemOuter.CenterEnd = v3{0, .9f, 0};
|
||||||
BloomStemOuter.Radius = .07f;
|
BloomStemOuter.Radius = .07f;
|
||||||
BloomStemOuter.SegmentsCount = 9;
|
BloomStemOuter.SegmentsCount = 9;
|
||||||
BloomStemOuter.SubsegmentsCount = 3;
|
BloomStemOuter.SubsegmentsCount = 3;
|
||||||
|
@ -136,8 +136,8 @@ BuildFlower(gs_string* OutputBuffer, flower_desc Desc)
|
||||||
#if 1
|
#if 1
|
||||||
// the flower stem
|
// the flower stem
|
||||||
loop_desc FlowerStem = {};
|
loop_desc FlowerStem = {};
|
||||||
FlowerStem.CenterStart = v3{0, -1.5f, 0} + Desc.Pos;
|
FlowerStem.CenterStart = v3{0, -1.5f, 0};
|
||||||
FlowerStem.CenterEnd = v3{0, .5f, 0} + Desc.Pos;
|
FlowerStem.CenterEnd = v3{0, .5f, 0};
|
||||||
FlowerStem.Radius = .05f;
|
FlowerStem.Radius = .05f;
|
||||||
FlowerStem.SegmentsCount = 6;
|
FlowerStem.SegmentsCount = 6;
|
||||||
FlowerStem.SubsegmentsCount = 1;
|
FlowerStem.SubsegmentsCount = 1;
|
||||||
|
@ -182,7 +182,7 @@ int main(int ArgCount, char** Args)
|
||||||
WriteAssemblyUARTOpen(&OutputBuffer0,
|
WriteAssemblyUARTOpen(&OutputBuffer0,
|
||||||
"Blumen Lumen - Silver Spring - 00",
|
"Blumen Lumen - Silver Spring - 00",
|
||||||
100,
|
100,
|
||||||
v3{0, 0, 0},
|
v3{-1, 0, 0},
|
||||||
21,
|
21,
|
||||||
"");
|
"");
|
||||||
WriteAssemblyUARTOpen(&OutputBuffer1,
|
WriteAssemblyUARTOpen(&OutputBuffer1,
|
||||||
|
@ -194,7 +194,7 @@ int main(int ArgCount, char** Args)
|
||||||
WriteAssemblyUARTOpen(&OutputBuffer2,
|
WriteAssemblyUARTOpen(&OutputBuffer2,
|
||||||
"Blumen Lumen - Silver Spring - 02",
|
"Blumen Lumen - Silver Spring - 02",
|
||||||
100,
|
100,
|
||||||
v3{0, 0, 0},
|
v3{1, 0, 0},
|
||||||
21,
|
21,
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ int main(int ArgCount, char** Args)
|
||||||
u32 BloomOuterChannels[] = { FSC(1, 0), FSC(1, 1), FSC(1, 2), FSC(1, 3), FSC(1, 4), FSC(1, 5), FSC(1, 6), FSC(1, 7), FSC(2, 0) };
|
u32 BloomOuterChannels[] = { FSC(1, 0), FSC(1, 1), FSC(1, 2), FSC(1, 3), FSC(1, 4), FSC(1, 5), FSC(1, 6), FSC(1, 7), FSC(2, 0) };
|
||||||
u32 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) };
|
u32 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) };
|
||||||
flower_desc F0 = {};
|
flower_desc F0 = {};
|
||||||
F0.Pos = v3{-1, 0, 0};
|
F0.Pos = v3{0, 0, 0};
|
||||||
F0.ComPort = "\\\\.\\COM11";
|
F0.ComPort = "\\\\.\\COM11";
|
||||||
F0.FlowerTagValue = "left";
|
F0.FlowerTagValue = "left";
|
||||||
F0.StemChannels = StemChannels;
|
F0.StemChannels = StemChannels;
|
||||||
|
@ -222,7 +222,7 @@ int main(int ArgCount, char** Args)
|
||||||
StripCount += BuildFlower(&OutputBuffer1, F1);
|
StripCount += BuildFlower(&OutputBuffer1, F1);
|
||||||
|
|
||||||
flower_desc F2 = {};
|
flower_desc F2 = {};
|
||||||
F2.Pos = v3{1, 0, 0};
|
F2.Pos = v3{0, 0, 0};
|
||||||
F2.ComPort = "\\\\.\\COM6";
|
F2.ComPort = "\\\\.\\COM6";
|
||||||
F2.FlowerTagValue = "right";
|
F2.FlowerTagValue = "right";
|
||||||
F2.StemChannels = StemChannels;
|
F2.StemChannels = StemChannels;
|
||||||
|
|
Loading…
Reference in New Issue