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);
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);
ui_widget_retained_state* ViewportState = ui_GetOrCreateRetainedState(Interface, ViewportLayout);
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

View File

@ -19,6 +19,12 @@ struct animation_timeline_state
animation_handle NextActiveAnim;
};
internal void
AnimationTimeline_SelectLayer(animation_timeline_state* TLState, s32 Layer)
{
TLState->SelectedAnimationLayer = Layer;
}
inline u32
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);
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);
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)
{
Assert(ReturningFrom->TypeIndex == PanelType_FileView);
@ -518,6 +502,8 @@ PANEL_MODAL_OVERRIDE_CALLBACK(LoadAnimationFileCallback)
internal void
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;
ui_interface* Interface = &State->Interface;
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
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;
gs_string TempString = PushString(State->Transient, 256);
@ -627,6 +615,7 @@ LayerList_DrawLayerButton (ui_interface* Interface, gs_string Name, rect2 Bounds
internal void
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_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
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;
// 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};
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++)
{
animation_block* AnimationBlockAt = ActiveAnim->Blocks_.Values + i;
if (AnimationBlockAt->Layer != l) continue;
// If either end is in the range, we should draw it
b32 RangeIsVisible = (FrameIsInRange(ViewRange, AnimationBlockAt->Range.Min) ||
@ -693,21 +738,81 @@ TimeRange_Render(animation_timeline_state* TimelineState, animation* ActiveAnim,
// we should still draw it.
RangeIsVisible |= (AnimationBlockAt->Range.Min <= ViewRange.Min &&
AnimationBlockAt->Range.Max>= ViewRange.Max);
if (RangeIsVisible)
{
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 (!RangeIsVisible) continue;
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;
DragBlockHandle.Generation = ActiveAnim->Blocks_.Generations[i];
if (Blocks[j].Bounds.Min.x > NewBlock.Bounds.Min.x)
{
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
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_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);
ui_BeginRow(Interface, 3);
ui_BeginRow(Interface, 2);
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)))
{
Interface->ActiveLayout->Bounds.Max.x += 128.0f;
@ -925,6 +1030,8 @@ GSMetaTag(panel_type_animation_timeline);
internal void
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* ActiveAnim = 0;

View File

@ -291,6 +291,13 @@ Patterns_IndexToHandle(s32 Index)
return Result;
}
internal bool
IsValid(animation_pattern_handle Handle)
{
bool Result = Handle.IndexPlusOne > 0;
return Result;
}
internal animation_pattern
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)
{
animation_block_array Result = {0};
Result.CountMax = CountMax;
Result.CountMax = Max(CountMax, 32);
Result.Values = PushArray(Storage, animation_block, Result.CountMax);
Result.Generations = PushArray(Storage, u32, Result.CountMax);
return Result;
@ -359,7 +366,7 @@ internal anim_layer_array
AnimLayerArray_Create(gs_memory_arena* Storage, u32 CountMax)
{
anim_layer_array Result = {0};
Result.CountMax = CountMax;
Result.CountMax = Max(CountMax, 32);
Result.Values = PushArray(Storage, anim_layer, Result.CountMax);
return Result;
}
@ -409,6 +416,8 @@ AnimationArray_Push(animation_array* Array, animation Value)
internal animation*
AnimationArray_Get(animation_array Array, animation_handle Handle)
{
DEBUG_TRACK_FUNCTION;
animation* Result = 0;
if (IsValid(Handle) && Handle.Index < (s32)Array.Count)
{
@ -541,6 +550,13 @@ SecondsToFrames(r32 Seconds, animation_system System)
return Result;
}
inline frame_range
FrameRange_Overlap(frame_range A, frame_range B)
{
frame_range Result = {};
}
inline bool
FrameIsInRange(frame_range Range, s32 Frame)
{
@ -679,6 +695,8 @@ AnimationSystem_CalculateAnimationFrame(animation_system* System,
animation* Animation,
gs_memory_arena* Arena)
{
DEBUG_TRACK_FUNCTION;
animation_frame Result = {0};
Result.LayersCount = Animation->Layers.Count;
Result.Layers = PushArray(Arena, animation_layer_frame, Result.LayersCount);
@ -793,5 +811,12 @@ AnimationSystem_NeedsRender(animation_system System)
return Result;
}
inline r32
AnimationSystem_GetCurrentTime(animation_system System)
{
r32 Result = System.CurrentFrame * System.SecondsPerFrame;
return Result;
}
#define FOLDHAUS_ANIMATION
#endif // FOLDHAUS_ANIMATION

View File

@ -122,6 +122,7 @@ AnimationSystem_BeginRenderBlockToLedBuffer(animation_system* System, animation_
r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame;
animation_pattern Pattern = Patterns_GetPattern(Patterns, Block.AnimationProcHandle);
Assert(Pattern.Proc);
if (System->Multithreaded && Pattern.Multithreaded)
{
@ -182,6 +183,8 @@ RenderAnimationToLedBuffer (animation_system* System,
gs_memory_arena* Transient,
context Context)
{
DEBUG_TRACK_FUNCTION;
led_buffer AccBuffer = LedBuffer_CreateCopyCleared(*AssemblyLedBuffer, Transient);
// Create the LayerLEDBuffers
@ -266,8 +269,7 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
{
DEBUG_TRACK_FUNCTION;
s32 CurrentFrame = System->CurrentFrame;
r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
r32 FrameTime = AnimationSystem_GetCurrentTime(*System);
#if 1
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.Layers.CountMax = Parser_ReadU32Value(&Parser, AnimField_LayersCount);
Result.Layers.Values = PushArray(Arena, anim_layer, Result.Layers.CountMax);
Result.Blocks_.CountMax = Parser_ReadU32Value(&Parser, AnimField_BlocksCount);
Result.Blocks_.Generations = PushArray(Arena, u32, Result.Blocks_.CountMax);
Result.Blocks_.Values = PushArray(Arena, animation_block, Result.Blocks_.CountMax);
u32 LayersNeeded = Parser_ReadU32Value(&Parser, AnimField_LayersCount);
u32 BlocksNeeded = Parser_ReadU32Value(&Parser, AnimField_BlocksCount);
Result.Layers = AnimLayerArray_Create(Arena, LayersNeeded);
Result.Blocks_ = AnimBlockArray_Create(Arena, BlocksNeeded);
if (Parser_ReadOpenStruct(&Parser, AnimField_PlayableRange))
{
@ -169,7 +167,7 @@ AnimParser_Parse(gs_string File, gs_memory_arena* Arena, animation_pattern_array
break;
}
}
Assert(IsValid(Block.AnimationProcHandle));
if (Parser_ReadCloseStruct(&Parser))
{
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);
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);
}
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->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->Strips = PushArray(&Assembly->Arena, v2_strip, Assembly->StripCount);

View File

@ -10,14 +10,23 @@
RELOAD_STATIC_DATA(ReloadStaticData)
{
app_state* State = (app_state*)Context.MemoryBase;
GlobalDebugServices = DebugServices;
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)
{
@ -38,6 +47,8 @@ INITIALIZE_APPLICATION(InitializeApplication)
AnimSysDesc.SecondsPerFrame = 1.0f / 24.0f;
State->AnimationSystem = AnimationSystem_Init(AnimSysDesc);
if (!Context.Headless)
{
interface_config IConfig = {0};
IConfig.FontSize = 14;
IConfig.PanelBG = v4{ .3f, .3f, .3f, 1.f };
@ -52,6 +63,10 @@ INITIALIZE_APPLICATION(InitializeApplication)
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->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128);
@ -59,17 +74,14 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->AssemblyDebugState.Brightness = 255;
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->UserSpaceDesc = BlumenLumen_UserSpaceCreate();
ReloadStaticData(Context, GlobalDebugServices);
ReloadStaticData(Context, GlobalDebugServices, true);
US_CustomInit(&State->UserSpaceDesc, State, Context);
GlobalDebugServices->Interface.RenderSculpture = true;
if (!Context.Headless)
{
// NOTE(pjs): This just sets up the default panel layout
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
@ -152,6 +164,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
{
Editor_Render(State, Context, RenderBuffer);
}
ResetWorkQueue(Context->GeneralWorkQueue);
Assert(State->UserSpaceDesc.UserData.Memory != 0);
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 "ss_blumen_lumen/sdf.h"
#include "patterns/blumen_patterns.h"
#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)
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);
#define CLEANUP_APPLICATION(name) void name(context Context, addressed_data_buffer_list* OutputData)
@ -213,6 +213,7 @@ struct context
b32 WindowIsVisible;
rect2 WindowBounds;
r64 TotalTime;
r32 DeltaTime;
mouse_state Mouse;
@ -236,6 +237,9 @@ struct context
system_time SystemTime_Last;
system_time SystemTime_Current;
//
bool Headless;
};
#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.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.062500f * Noise3D(Pp); Pp = Pp * 2.04;
F += 0.062500f * Noise3D(Pp + Tt); Pp = Pp * 2.04;
F += 0.015625f * Noise3D(Pp + Tv);
F = F / 0.984375f;
@ -319,49 +319,6 @@ Voronoise(v2 P, r32 U, r32 V)
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
V4ToRGBPixel(v4 C)
{
@ -410,166 +367,6 @@ GetColor(v4* Colors, u32 ColorsCount, r32 Percent)
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 Result = {};
@ -697,6 +494,22 @@ while (Hue > 360.0f) { Hue -= 360.0f; }
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
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
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);
@ -748,49 +561,7 @@ Pattern_HueFade(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
}
internal void
Pattern_AllGreen(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)
Pattern_RadialRainbow(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) });
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);
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);
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
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;
phrase_hue Hue = BLState->AssemblyColors[Assembly.AssemblyIndex % 3];
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;
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 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++)
{
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));
Noise = RemapR32(Noise, -1, 1, 0, 1);
Noise = Smoothstep(Noise, 0, 1);
u8 NV = (u8)(Noise * 255);
r32 PercentMid = Clamp01(1.0f - Abs(P.y - Mid) / MidD);
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 - PercentMid, 4);
PercentMid = Clamp01(PercentMid + N);
v3 BSeed = v3{P.z, P.x, P.y};
r32 BNoise = 1.0f; //Fbm3D(BSeed / 50);
r32 PercentBot = Clamp01(1.0f - ((P.y - Bot) / BotD));
v4 C = V4Lerp(BNoise, C0, C1);
C = C * BNoise;
v4 TopC = (C0 * PercentTop);
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] = pixel{NV, NV, NV};
}
}
@ -1065,7 +684,7 @@ Pattern_Patchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32
DEBUG_TRACK_FUNCTION;
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 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);
v4 CB = C1 * NoiseB;
v4 C = CA + CB;
v4 C = (C0 * NoiseA) + (C1 * NoiseB);
C /= (NoiseA + NoiseB);
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
Pattern_Leafy(led_buffer* Leds, led_buffer_range Range, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
{
DEBUG_TRACK_FUNCTION;
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 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
v4 C2 = HSVToRGB({Hue.Hue2, 1, 1, 1});
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
{
v4 P = Leds->Positions[LedIndex];
#if 0
r32 RefPos = P.y + Noise2D(v2{P.x, P.z} * 10);
v4 C = {};
r32 B = 0;
r32 BandWidth = 5;
r32 TransitionPeriod = 30.0f;
u32 BandCount = 10;
// NOTE(PS): initializing the Random seed inside the Led Loop
// so that the bands are consistently calculated for each led
// 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++)
{
r32 BandSeed = Hash1((r32)Band);
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 += Leafy_BandSDF(P.xyz, &Random, Time);
}
B = Clamp(0, B, 1);
B = Clamp01(B);
r32 BandCP = (P.y + 100) / 200;
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;
}
C = WhiteV4 * B;
Leds->Colors[LedIndex] = V4ToRGBPixel(C);
}
}
@ -1159,33 +779,44 @@ Pattern_LeafyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly,
{
DEBUG_TRACK_FUNCTION;
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 C1 = HSVToRGB({Hue.Hue1, 1, 1, 1});
v4 C2 = HSVToRGB({Hue.Hue2, 1, 1, 1});
for (u32 LedIndex = Range.First; LedIndex < Range.OnePastLast; LedIndex++)
{
v4 P = Leds->Positions[LedIndex];
r32 LedRange = 300.0f;
r32 ScaleFactor = 1.0f / LedRange;
v3 Pp = P.xyz + v3{150, 100, 0};
r32 NoiseA = Fbm3D((Pp / 35), Time * 0.5f);
//NoiseA = PowR32(NoiseA, 3);
r32 NoiseA = Fbm3D((Pp / 18), Time * 0.25f);
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 = 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);
}
}
internal void
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;
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 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;
for (u32 StripIndex = 0; StripIndex < Assembly.StripCount; StripIndex++)
{
v2_strip Strip = Assembly.Strips[StripIndex];
r32 LightHue = LerpR32(NextRandomUnilateral(&Random),
LightHueMin,
LightHueMax);
r32 LightStartHeight = NextRandomUnilateral(&Random);
r32 LightSpeed = LerpR32(NextRandomUnilateral(&Random),
LightSpeedMin,
@ -1224,11 +844,99 @@ Pattern_WavyPatchy(led_buffer* Leds, led_buffer_range Range, assembly Assembly,
u32 LedIndex = Strip.LedLUT[StripLedIndex];
r32 PctTail = ((r32)i / (r32)LightTailLength);
v4 C = HSVToRGB(v4{LightHue, 1, 1, 1}) * PctTail;
v4 C = WhiteV4 * PctTail;
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
#endif // BLUMEN_PATTERNS_H

View File

@ -430,14 +430,15 @@ Win32_SendAddressedDataBuffer_Job(gs_thread_context Context, gs_data Arg)
}
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;
if (HotLoadDLL(DLL))
{
SetApplicationLinks(Context, *DLL, WorkQueue);
Context->ReloadStaticData(*Context, GlobalDebugServices);
Context->ReloadStaticData(*Context, GlobalDebugServices, AppReady);
Success = true;
OutputDebugStringA("Reloaded DLL\n");
}
else if(ShouldError)
{
@ -609,6 +610,20 @@ WinMain (
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);
Win32UpdateWindowDimension(&MainWindow);
@ -617,11 +632,7 @@ WinMain (
OpenGLWindowInfo.AlphaBits = 8;
OpenGLWindowInfo.DepthBits = 0;
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");
@ -657,7 +668,7 @@ WinMain (
*Context.SocketManager = CreatePlatformSocketManager(Win32ConnectSocket, Win32CloseSocket, Win32SocketQueryStatus, Win32SocketPeek, Win32SocketReceive, Win32SocketSend);
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();
@ -708,12 +719,13 @@ WinMain (
ResetInputQueue(&InputQueue);
ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false);
ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, false, true);
AddressedDataBufferList_Clear(&OutputData);
if (!Context.Headless)
{
Mouse_Update(MainWindow, &Context);
MSG Message;
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}};
RenderBuffer.ViewWidth = MainWindow.Width;
RenderBuffer.ViewHeight = MainWindow.Height;
Context.DeltaTime = LastFrameSecondsElapsed;
}
#if 0
gs_string T = PushStringF(Context.ThreadContext.Transient, 256, "%f\n", Context.DeltaTime);
NullTerminate(&T);
OutputDebugStringA(T.Str);
#endif
Context.DeltaTime = LastFrameSecondsElapsed;
Context.TotalTime += (r64)Context.DeltaTime;
Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData);
Win32_SendOutputData(ThreadContext, OutputData);
if (!Context.Headless)
{
RenderCommandBuffer(RenderBuffer);
ClearRenderBuffer(&RenderBuffer);
@ -744,6 +755,7 @@ WinMain (
HDC DeviceContext = GetDC(MainWindow.Handle);
SwapBuffers(DeviceContext);
ReleaseDC(MainWindow.Handle, DeviceContext);
}
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
@ -767,8 +779,6 @@ WinMain (
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
Win32WorkQueue_Cleanup();
//Win32_TestCode_SocketReading_Cleanup();
Win32SocketSystem_Cleanup();
return 0;

View File

@ -194,28 +194,18 @@ BlumenLumen_LoadPatterns(app_state* State)
}
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_HueFade, 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_Rainbow, PATTERN_MULTITHREADED);
Patterns_PushPattern(Patterns, Pattern_BasicFlowers, PATTERN_MULTITHREADED);
// 15
Patterns_PushPattern(Patterns, Pattern_Wavy, PATTERN_MULTITHREADED);
Patterns_PushPattern(Patterns, Pattern_Patchy, PATTERN_MULTITHREADED);
Patterns_PushPattern(Patterns, Pattern_Leafy, PATTERN_MULTITHREADED);
Patterns_PushPattern(Patterns, Pattern_LeafyPatchy, PATTERN_MULTITHREADED);
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
@ -240,6 +230,8 @@ BlumenLumen_CustomInit(app_state* State, context Context)
BLState->MicListenJobData.IncomingMsgQueue = &BLState->IncomingMsgQueue;
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
BLState->PatternSpeed = GlobalAnimSpeed;
#if 1
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData);
#endif
@ -267,38 +259,6 @@ BlumenLumen_CustomInit(app_state* State, context Context)
&State->Permanent);
#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,
State->Patterns,
Context,
@ -307,6 +267,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
#else
BLState->ModeAnimations[BlumenPattern_Standard] = LoadAllAnimationsInDir(AmbientPatternFolder, 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);
#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
if (BLState->PatternMode == BlumenPattern_VoiceCommand)
{

View File

@ -155,6 +155,7 @@ struct blumen_lumen_state
system_time LastSendTime;
phrase_hue StandardPatternHues;
phrase_hue AssemblyColors[BL_FLOWER_COUNT];
u32 LastAssemblyColorSet;
@ -172,6 +173,7 @@ struct blumen_lumen_state
phrase_hue_map PhraseHueMap;
system_time TimeLastSetToVoiceMode;
r32 PatternSpeed;
// Debug
motor_packet DEBUG_PendingMotorPacket;
bool DEBUG_IgnoreWeatherDimmingLeds;
@ -179,6 +181,26 @@ struct blumen_lumen_state
#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?
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

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
// the bloom stem inner
loop_desc BloomStemInner = {};
BloomStemInner.CenterStart = v3{0, 1.4f, 0} + Desc.Pos;
BloomStemInner.CenterEnd = v3{0, .9f, 0} + Desc.Pos;
BloomStemInner.CenterStart = v3{0, 1.4f, 0};
BloomStemInner.CenterEnd = v3{0, .9f, 0};
BloomStemInner.Radius = .05f;
BloomStemInner.SegmentsCount = 6;
BloomStemInner.SubsegmentsCount = 3;
@ -120,8 +120,8 @@ BuildFlower(gs_string* OutputBuffer, flower_desc Desc)
// the bloom stem outer
loop_desc BloomStemOuter = {};
BloomStemOuter.CenterStart = v3{0, .5f, 0} + Desc.Pos;
BloomStemOuter.CenterEnd = v3{0, .9f, 0} + Desc.Pos;
BloomStemOuter.CenterStart = v3{0, .5f, 0};
BloomStemOuter.CenterEnd = v3{0, .9f, 0};
BloomStemOuter.Radius = .07f;
BloomStemOuter.SegmentsCount = 9;
BloomStemOuter.SubsegmentsCount = 3;
@ -136,8 +136,8 @@ BuildFlower(gs_string* OutputBuffer, flower_desc Desc)
#if 1
// the flower stem
loop_desc FlowerStem = {};
FlowerStem.CenterStart = v3{0, -1.5f, 0} + Desc.Pos;
FlowerStem.CenterEnd = v3{0, .5f, 0} + Desc.Pos;
FlowerStem.CenterStart = v3{0, -1.5f, 0};
FlowerStem.CenterEnd = v3{0, .5f, 0};
FlowerStem.Radius = .05f;
FlowerStem.SegmentsCount = 6;
FlowerStem.SubsegmentsCount = 1;
@ -182,7 +182,7 @@ int main(int ArgCount, char** Args)
WriteAssemblyUARTOpen(&OutputBuffer0,
"Blumen Lumen - Silver Spring - 00",
100,
v3{0, 0, 0},
v3{-1, 0, 0},
21,
"");
WriteAssemblyUARTOpen(&OutputBuffer1,
@ -194,7 +194,7 @@ int main(int ArgCount, char** Args)
WriteAssemblyUARTOpen(&OutputBuffer2,
"Blumen Lumen - Silver Spring - 02",
100,
v3{0, 0, 0},
v3{1, 0, 0},
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 BloomInnerChannels[] = { FSC(0, 0), FSC(0, 1), FSC(0, 2), FSC(0, 3), FSC(0, 4), FSC(0, 5) };
flower_desc F0 = {};
F0.Pos = v3{-1, 0, 0};
F0.Pos = v3{0, 0, 0};
F0.ComPort = "\\\\.\\COM11";
F0.FlowerTagValue = "left";
F0.StemChannels = StemChannels;
@ -222,7 +222,7 @@ int main(int ArgCount, char** Args)
StripCount += BuildFlower(&OutputBuffer1, F1);
flower_desc F2 = {};
F2.Pos = v3{1, 0, 0};
F2.Pos = v3{0, 0, 0};
F2.ComPort = "\\\\.\\COM6";
F2.FlowerTagValue = "right";
F2.StemChannels = StemChannels;