shipping time

This commit is contained in:
PS 2021-03-30 19:55:54 -07:00
parent 6b137154bc
commit 963415335b
17 changed files with 581 additions and 690 deletions

View File

@ -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);
} }

View File

@ -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

View File

@ -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,32 +711,108 @@ TimeRange_Render(animation_timeline_state* TimelineState, animation* ActiveAnim,
handle DragBlockHandle = {0}; handle DragBlockHandle = {0};
if (ActiveAnim) if (ActiveAnim)
{ {
for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++) 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++)
{ {
animation_block* AnimationBlockAt = ActiveAnim->Blocks_.Values + i; BlocksCount = 0;
FrontBlocksCount = 0;
BackBlocksCount = 0;
// If either end is in the range, we should draw it for (u32 i = 0; i < ActiveAnim->Blocks_.Count; i++)
b32 RangeIsVisible = (FrameIsInRange(ViewRange, AnimationBlockAt->Range.Min) ||
FrameIsInRange(ViewRange, AnimationBlockAt->Range.Max));
// If neither end is in the range, but the ends surround the visible range,
// we should still draw it.
RangeIsVisible |= (AnimationBlockAt->Range.Min <= ViewRange.Min &&
AnimationBlockAt->Range.Max>= ViewRange.Max);
if (RangeIsVisible)
{ {
v4 BlockColor = BlackV4; animation_block* AnimationBlockAt = ActiveAnim->Blocks_.Values + i;
if (SelectedBlockHandle.Index == i && SelectedBlockHandle.Generation == ActiveAnim->Blocks_.Generations[i]) if (AnimationBlockAt->Layer != l) continue;
{
BlockColor = PinkV4;
}
rect2 BlockBounds = DrawAnimationBlock(*AnimationBlockAt, BlockColor, ViewRange, Bounds, Interface->RenderBuffer);
if (PointIsInRect(BlockBounds, Interface->Mouse.Pos)) // If either end is in the range, we should draw it
b32 RangeIsVisible = (FrameIsInRange(ViewRange, AnimationBlockAt->Range.Min) ||
FrameIsInRange(ViewRange, AnimationBlockAt->Range.Max));
// If neither end is in the range, but the ends surround the visible range,
// we should still draw it.
RangeIsVisible |= (AnimationBlockAt->Range.Min <= ViewRange.Min &&
AnimationBlockAt->Range.Max>= ViewRange.Max);
if (!RangeIsVisible) continue;
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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -10,13 +10,22 @@
RELOAD_STATIC_DATA(ReloadStaticData) RELOAD_STATIC_DATA(ReloadStaticData)
{ {
app_state* State = (app_state*)Context.MemoryBase;
GlobalDebugServices = DebugServices; GlobalDebugServices = DebugServices;
State->PanelSystem.PanelDefs = GlobalPanelDefs;
State->PanelSystem.PanelDefsCount = GlobalPanelDefsCount;
US_LoadPatterns(&State->UserSpaceDesc, State, Context); if (AppReady)
{
app_state* State = (app_state*)Context.MemoryBase;
State->PanelSystem.PanelDefs = GlobalPanelDefs;
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);
}
} }
INITIALIZE_APPLICATION(InitializeApplication) INITIALIZE_APPLICATION(InitializeApplication)
@ -38,19 +47,25 @@ 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);
interface_config IConfig = {0}; if (!Context.Headless)
IConfig.FontSize = 14; {
IConfig.PanelBG = v4{ .3f, .3f, .3f, 1.f }; interface_config IConfig = {0};
IConfig.ButtonColor_Inactive = BlackV4; IConfig.FontSize = 14;
IConfig.ButtonColor_Active = v4{ .1f, .1f, .1f, 1.f }; IConfig.PanelBG = v4{ .3f, .3f, .3f, 1.f };
IConfig.ButtonColor_Selected = v4{ .3f, .3f, .3f, 1.f }; IConfig.ButtonColor_Inactive = BlackV4;
IConfig.TextColor = WhiteV4; IConfig.ButtonColor_Active = v4{ .1f, .1f, .1f, 1.f };
IConfig.ListBGColors[0] = v4{ .16f, .16f, .16f, 1.f }; IConfig.ButtonColor_Selected = v4{ .3f, .3f, .3f, 1.f };
IConfig.ListBGColors[1] = v4{ .18f, .18f, .18f, 1.f }; IConfig.TextColor = WhiteV4;
IConfig.ListBGHover = v4{ .22f, .22f, .22f, 1.f }; IConfig.ListBGColors[0] = v4{ .16f, .16f, .16f, 1.f };
IConfig.ListBGSelected = v4{ .44f, .44f, .44f, 1.f }; IConfig.ListBGColors[1] = v4{ .18f, .18f, .18f, 1.f };
IConfig.Margin = v2{5, 5}; IConfig.ListBGHover = v4{ .22f, .22f, .22f, 1.f };
State->Interface = ui_InterfaceCreate(Context, IConfig, &State->Permanent); IConfig.ListBGSelected = v4{ .44f, .44f, .44f, 1.f };
IConfig.Margin = v2{5, 5};
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);
@ -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);

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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,20 +610,30 @@ WinMain (
if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1; if (!SetWorkingDirectory(HInstance, ThreadContext)) return 1;
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
Win32UpdateWindowDimension(&MainWindow);
win32_opengl_window_info OpenGLWindowInfo = {};
OpenGLWindowInfo.ColorBits = 32;
OpenGLWindowInfo.AlphaBits = 8;
OpenGLWindowInfo.DepthBits = 0;
CreateOpenGLWindowContext(OpenGLWindowInfo, &MainWindow);
context Context = {}; context Context = {};
Context.ThreadContext = ThreadContext; Context.ThreadContext = ThreadContext;
Context.MemorySize = MB(64); Context.MemorySize = MB(64);
Context.MemoryBase = (u8*)Win32Alloc(Context.MemorySize, 0); 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);
Win32UpdateWindowDimension(&MainWindow);
win32_opengl_window_info OpenGLWindowInfo = {};
OpenGLWindowInfo.ColorBits = 32;
OpenGLWindowInfo.AlphaBits = 8;
OpenGLWindowInfo.DepthBits = 0;
CreateOpenGLWindowContext(OpenGLWindowInfo, &MainWindow);
}
gs_memory_arena PlatformPermanent = CreateMemoryArena(Context.ThreadContext.Allocator, "Platform Memory"); gs_memory_arena PlatformPermanent = CreateMemoryArena(Context.ThreadContext.Allocator, "Platform Memory");
s64 PerformanceCountFrequency = GetPerformanceFrequency(); s64 PerformanceCountFrequency = GetPerformanceFrequency();
@ -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,42 +719,43 @@ WinMain (
ResetInputQueue(&InputQueue); ResetInputQueue(&InputQueue);
ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false); ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false, true);
AddressedDataBufferList_Clear(&OutputData); AddressedDataBufferList_Clear(&OutputData);
Mouse_Update(MainWindow, &Context); if (!Context.Headless)
MSG Message;
while (PeekMessageA(&Message, MainWindow.Handle, 0, 0, PM_REMOVE))
{ {
DEBUG_TRACK_SCOPE(PeekWindowsMessages); Mouse_Update(MainWindow, &Context);
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse); MSG Message;
while (PeekMessageA(&Message, MainWindow.Handle, 0, 0, PM_REMOVE))
{
DEBUG_TRACK_SCOPE(PeekWindowsMessages);
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Context.Mouse);
}
Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
RenderBuffer.ViewWidth = MainWindow.Width;
RenderBuffer.ViewHeight = MainWindow.Height;
} }
Context.WindowBounds = rect2{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
RenderBuffer.ViewWidth = MainWindow.Width;
RenderBuffer.ViewHeight = MainWindow.Height;
Context.DeltaTime = LastFrameSecondsElapsed; Context.DeltaTime = LastFrameSecondsElapsed;
Context.TotalTime += (r64)Context.DeltaTime;
#if 0
gs_string T = PushStringF(Context.ThreadContext.Transient, 256, "%f\n", 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);
RenderCommandBuffer(RenderBuffer); if (!Context.Headless)
ClearRenderBuffer(&RenderBuffer); {
RenderCommandBuffer(RenderBuffer);
Mouse_Advance(&Context); ClearRenderBuffer(&RenderBuffer);
HDC DeviceContext = GetDC(MainWindow.Handle); Mouse_Advance(&Context);
SwapBuffers(DeviceContext);
ReleaseDC(MainWindow.Handle, DeviceContext); HDC DeviceContext = GetDC(MainWindow.Handle);
SwapBuffers(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;

View File

@ -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)
{ {

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;