debug and profiler improvements. implemented sending data to multiple destinations on a per strip basis, rather than a full sculpture basis. new patterns. Added user data to patterns.
This commit is contained in:
parent
914523cb60
commit
4798002dfc
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// File: blumen_lumen.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2021-01-15
|
||||||
|
//
|
||||||
|
#ifndef BLUMEN_LUMEN_H
|
||||||
|
|
||||||
|
typedef struct motor_packet
|
||||||
|
{
|
||||||
|
u8 FlowerPositions[3];
|
||||||
|
} motor_packet;
|
||||||
|
|
||||||
|
|
||||||
|
#define BLUMEN_LUMEN_H
|
||||||
|
#endif // BLUMEN_LUMEN_H
|
|
@ -897,6 +897,8 @@ AnimationTimeline_Render(panel* Panel, rect2 PanelBounds, render_command_buffer*
|
||||||
{
|
{
|
||||||
animation_timeline_state* TimelineState = Panel_GetStateStruct(Panel, animation_timeline_state);
|
animation_timeline_state* TimelineState = Panel_GetStateStruct(Panel, animation_timeline_state);
|
||||||
|
|
||||||
|
ui_FillRect(&State->Interface, PanelBounds, v4{.1f,.1f,.1f,1.f});
|
||||||
|
|
||||||
rect2 TimelineBounds, InfoBounds;
|
rect2 TimelineBounds, InfoBounds;
|
||||||
RectVSplit(PanelBounds, 300, &InfoBounds, &TimelineBounds);
|
RectVSplit(PanelBounds, 300, &InfoBounds, &TimelineBounds);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// File: foldhaus_panel_assembly_debug.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2021-01-15
|
||||||
|
//
|
||||||
|
#ifndef FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H
|
||||||
|
|
||||||
|
GSMetaTag(panel_init);
|
||||||
|
GSMetaTag(panel_type_file_view);
|
||||||
|
internal void
|
||||||
|
AssemblyDebug_Init(panel* Panel, app_state* State, context Context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GSMetaTag(panel_cleanup);
|
||||||
|
GSMetaTag(panel_type_file_view);
|
||||||
|
internal void
|
||||||
|
AssemblyDebug_Cleanup(panel* Panel, app_state* State)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GSMetaTag(panel_render);
|
||||||
|
GSMetaTag(panel_type_file_view);
|
||||||
|
internal void
|
||||||
|
AssemblyDebug_Render(panel* Panel, rect2 PanelBounds, render_command_buffer* RenderBuffer, app_state* State, context Context)
|
||||||
|
{
|
||||||
|
ui_interface* Interface = &State->Interface;
|
||||||
|
ui_PushLayout(Interface, PanelBounds, LayoutDirection_TopDown, MakeString("Assembly Debug Layout"));
|
||||||
|
|
||||||
|
State->AssemblyDebugState.TargetAssembly = ui_LabeledTextEntryU64(Interface, MakeString("Assembly"), State->AssemblyDebugState.TargetAssembly);
|
||||||
|
|
||||||
|
State->AssemblyDebugState.TargetStrip = ui_LabeledTextEntryU64(Interface, MakeString("Strip"), State->AssemblyDebugState.TargetStrip);
|
||||||
|
|
||||||
|
|
||||||
|
gs_string OverrideStr = MakeString(OverrideTypeStrings[State->AssemblyDebugState.Override]);
|
||||||
|
if (ui_BeginLabeledDropdown(Interface, MakeString("Override"), OverrideStr))
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < ADS_Override_Count; i++)
|
||||||
|
{
|
||||||
|
if (ui_Button(Interface, MakeString(OverrideTypeStrings[i])))
|
||||||
|
{
|
||||||
|
State->AssemblyDebugState.Override = (override_type)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui_EndLabeledDropdown(Interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H
|
||||||
|
#endif // FOLDHAUS_PANEL_ASSEMBLY_DEBUG_H
|
|
@ -37,52 +37,68 @@ RenderProfiler_ScopeVisualization(ui_interface* Interface, ui_widget* Layout, de
|
||||||
|
|
||||||
rect2 Bounds = ui_LayoutRemaining(*Layout);
|
rect2 Bounds = ui_LayoutRemaining(*Layout);
|
||||||
r32 Width = Rect2Width(Bounds);
|
r32 Width = Rect2Width(Bounds);
|
||||||
r32 DepthHeight = 64;
|
r32 DepthHeight = 32;
|
||||||
|
|
||||||
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
|
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
|
||||||
s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles;
|
r32 FrameTotalCycles = (r32)(VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles);
|
||||||
|
|
||||||
debug_scope_record_list* ThreadScopeCalls = GetScopeListForThreadInFrame(GlobalDebugServices,
|
r32 NextThreadTop = Bounds.Max.y;
|
||||||
VisibleFrame);
|
|
||||||
|
|
||||||
gs_string String = PushString(Transient, 256);
|
for (s32 t = 0; t < VisibleFrame->ThreadCount; t++)
|
||||||
for (s32 i = 0; i < ThreadScopeCalls->Count; i++)
|
|
||||||
{
|
{
|
||||||
scope_record* Record = ThreadScopeCalls->Calls + i;
|
debug_scope_record_list ThreadCalls = VisibleFrame->ThreadCalls[t];
|
||||||
scope_name* Name = GetOrAddNameHashEntry(VisibleFrame, Record->NameHash);
|
|
||||||
r32 PercentStart = (r32)(Record->StartCycles - FrameStartCycles) / (r32)FrameTotalCycles;
|
|
||||||
r32 PercentEnd = (r32)(Record->EndCycles - FrameStartCycles) / (r32)FrameTotalCycles;
|
|
||||||
|
|
||||||
r32 PixelStart = Bounds.Min.x + (Width * PercentStart);
|
gs_string String = PushString(Transient, 256);
|
||||||
r32 PixelEnd = Bounds.Min.x + (Width * PercentEnd);
|
|
||||||
r32 MinY = Bounds.Max.y - ((Record->CallDepth + 1) * DepthHeight);
|
r32 ThreadScopeMin = Bounds.Max.y;
|
||||||
rect2 ScopeBounds = {
|
|
||||||
v2{ PixelStart, MinY },
|
for (s32 i = 0; i < ThreadCalls.Count; i++)
|
||||||
v2{ PixelEnd, MinY + (DepthHeight - 4) }
|
|
||||||
};
|
|
||||||
if (Rect2Width(ScopeBounds) >= 1)
|
|
||||||
{
|
{
|
||||||
v4 Color = ThreadColors[0];
|
scope_record* Record = ThreadCalls.Calls + i;
|
||||||
if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos))
|
scope_name* Name = GetOrAddNameHashEntry(VisibleFrame, Record->NameHash);
|
||||||
{
|
s64 OffsetStart = Record->StartCycles - FrameStartCycles;
|
||||||
Color = GreenV4;
|
s64 OffsetEnd = Record->EndCycles - FrameStartCycles;
|
||||||
|
r32 PercentStart = (r32)(OffsetStart) / FrameTotalCycles;
|
||||||
ui_BeginMousePopup(Interface, rect2{ 25, 25, 300, 57 }, LayoutDirection_TopDown, MakeString("Hover"));
|
r32 PercentEnd = (r32)(OffsetEnd) / FrameTotalCycles;
|
||||||
{
|
r32 PercentWidth = PercentEnd - PercentStart;
|
||||||
s64 Cycles = (Record->EndCycles - Record->StartCycles);
|
|
||||||
r64 PercentFrame = (r64)(Cycles) / (r64)(FrameTotalCycles);
|
|
||||||
PrintF(&String, "%S : %.2f%% frame | %dcy",
|
|
||||||
Name->Name,
|
|
||||||
PercentFrame,
|
|
||||||
Cycles);
|
|
||||||
ui_Label(Interface, String);
|
|
||||||
}
|
|
||||||
ui_EndMousePopup(Interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_FillRect(Interface, ScopeBounds, Color);
|
rect2 ScopeBounds = {
|
||||||
ui_OutlineRect(Interface, ScopeBounds, 1, BlackV4);
|
v2{0, 0},
|
||||||
|
v2{PercentWidth * Width, DepthHeight - 4},
|
||||||
|
};
|
||||||
|
v2 Offset = {
|
||||||
|
Bounds.Min.x + (PercentStart * Width),
|
||||||
|
NextThreadTop - ((Record->CallDepth + 1) * DepthHeight)
|
||||||
|
};
|
||||||
|
ScopeBounds = Rect2Translate(ScopeBounds, Offset);
|
||||||
|
ThreadScopeMin = Min(ScopeBounds.Min.y, ThreadScopeMin);
|
||||||
|
|
||||||
|
if (Rect2Width(ScopeBounds) >= 1)
|
||||||
|
{
|
||||||
|
v4 Color = ThreadColors[t];
|
||||||
|
if (PointIsInRect(ScopeBounds, Interface->Mouse.Pos))
|
||||||
|
{
|
||||||
|
Color = GreenV4;
|
||||||
|
|
||||||
|
ui_BeginMousePopup(Interface, rect2{ 25, 25, 300, 57 }, LayoutDirection_TopDown, MakeString("Hover"));
|
||||||
|
{
|
||||||
|
s64 Cycles = (Record->EndCycles - Record->StartCycles);
|
||||||
|
r32 PercentFrame = (r32)(Cycles) / FrameTotalCycles;
|
||||||
|
PrintF(&String, "%S : %.2f%% frame | %dcy",
|
||||||
|
Name->Name,
|
||||||
|
PercentFrame,
|
||||||
|
Cycles);
|
||||||
|
ui_Label(Interface, String);
|
||||||
|
}
|
||||||
|
ui_EndMousePopup(Interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_FillRect(Interface, ScopeBounds, Color);
|
||||||
|
ui_OutlineRect(Interface, ScopeBounds, 1, BlackV4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NextThreadTop = ThreadScopeMin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// Creation Date: 2020-10-17
|
// Creation Date: 2020-10-17
|
||||||
//
|
//
|
||||||
#ifndef FOLDHAUS_PANEL_TYPES_CPP
|
#ifndef FOLDHAUS_PANEL_TYPES_CPP
|
||||||
global s32 GlobalPanelDefsCount = 6;
|
global s32 GlobalPanelDefsCount = 7;
|
||||||
global panel_definition GlobalPanelDefs[] = {
|
global panel_definition GlobalPanelDefs[] = {
|
||||||
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount },
|
{ "File View", 9, FileView_Init, FileView_Cleanup, FileView_Render, FileView_Commands, FileView_CommandsCount },
|
||||||
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount },
|
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands, SculptureView_CommandsCount },
|
||||||
|
@ -12,6 +12,7 @@ global panel_definition GlobalPanelDefs[] = {
|
||||||
{ "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount },
|
{ "Dmx View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, DMXView_Commands, DMXView_CommandsCount },
|
||||||
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
|
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, HierarchyView_Commands, HierarchyView_CommandsCount },
|
||||||
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
|
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, ProfilerView_Commands, ProfilerView_CommandsCount },
|
||||||
|
{ "Assembly Debug", 14, AssemblyDebug_Init, AssemblyDebug_Cleanup, AssemblyDebug_Render, 0, 0 },
|
||||||
};
|
};
|
||||||
#define FOLDHAUS_PANEL_TYPES_CPP
|
#define FOLDHAUS_PANEL_TYPES_CPP
|
||||||
#endif // FOLDHAUS_PANEL_TYPES_CPP
|
#endif // FOLDHAUS_PANEL_TYPES_CPP
|
|
@ -12,6 +12,7 @@ enum panel_type {
|
||||||
PanelType_HierarchyView,
|
PanelType_HierarchyView,
|
||||||
PanelType_NodeGraph,
|
PanelType_NodeGraph,
|
||||||
PanelType_ProfilerView,
|
PanelType_ProfilerView,
|
||||||
|
PanelType_AssemblyDebug,
|
||||||
};
|
};
|
||||||
#define FOLDHAUS_PANEL_TYPES_H
|
#define FOLDHAUS_PANEL_TYPES_H
|
||||||
#endif // FOLDHAUS_PANEL_TYPES_H
|
#endif // FOLDHAUS_PANEL_TYPES_H
|
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
#ifndef FOLDHAUS_ANIMATION
|
#ifndef FOLDHAUS_ANIMATION
|
||||||
|
|
||||||
#define ANIMATION_PROC(name) void name(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
#define ANIMATION_PROC(name) void name(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
typedef ANIMATION_PROC(animation_proc);
|
typedef ANIMATION_PROC(animation_proc);
|
||||||
|
|
||||||
struct frame_range
|
struct frame_range
|
||||||
|
|
|
@ -81,20 +81,22 @@ LedBlend_GetProc(blend_mode BlendMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
AnimationSystem_RenderBlockToLedBuffer(animation_system* System, animation_block Block, led_buffer* Buffer, assembly Assembly, animation_pattern_array Patterns, gs_memory_arena* Transient)
|
AnimationSystem_RenderBlockToLedBuffer(animation_system* System, animation_block Block, led_buffer* Buffer, assembly Assembly, animation_pattern_array Patterns, gs_memory_arena* Transient,
|
||||||
|
u8* UserData)
|
||||||
{
|
{
|
||||||
u32 FramesIntoBlock = System->CurrentFrame - Block.Range.Min;
|
u32 FramesIntoBlock = System->CurrentFrame - Block.Range.Min;
|
||||||
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);
|
||||||
Pattern.Proc(Buffer, Assembly, SecondsIntoBlock, Transient);
|
Pattern.Proc(Buffer, Assembly, SecondsIntoBlock, Transient, UserData);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Assemblies,
|
AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Assemblies,
|
||||||
led_system* LedSystem,
|
led_system* LedSystem,
|
||||||
animation_pattern_array Patterns,
|
animation_pattern_array Patterns,
|
||||||
gs_memory_arena* Transient)
|
gs_memory_arena* Transient,
|
||||||
|
u8* UserData)
|
||||||
{
|
{
|
||||||
s32 CurrentFrame = System->CurrentFrame;
|
s32 CurrentFrame = System->CurrentFrame;
|
||||||
r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
|
r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
|
||||||
|
@ -148,14 +150,14 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
|
||||||
{
|
{
|
||||||
led_buffer TempBuffer = LayerBuffers[Layer].HotBuffer;
|
led_buffer TempBuffer = LayerBuffers[Layer].HotBuffer;
|
||||||
animation_block Block = LayerFrame.Hot;
|
animation_block Block = LayerFrame.Hot;
|
||||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient);
|
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient, UserData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LayerFrame.HasNextHot)
|
if (LayerFrame.HasNextHot)
|
||||||
{
|
{
|
||||||
led_buffer TempBuffer = LayerBuffers[Layer].NextHotBuffer;
|
led_buffer TempBuffer = LayerBuffers[Layer].NextHotBuffer;
|
||||||
animation_block Block = LayerFrame.NextHot;
|
animation_block Block = LayerFrame.NextHot;
|
||||||
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient);
|
AnimationSystem_RenderBlockToLedBuffer(System, Block, &TempBuffer, *Assembly, Patterns, Transient, UserData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,6 @@ struct assembly_array
|
||||||
assembly* Values;
|
assembly* Values;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
internal led_buffer*
|
internal led_buffer*
|
||||||
LedSystemGetBuffer(led_system* System, u32 Index)
|
LedSystemGetBuffer(led_system* System, u32 Index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
//
|
||||||
|
// File: foldhaus_assembly_debug.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2021-01-15
|
||||||
|
//
|
||||||
|
#ifndef FOLDHAUS_ASSEMBLY_DEBUG_H
|
||||||
|
|
||||||
|
enum override_type
|
||||||
|
{
|
||||||
|
ADS_Override_None,
|
||||||
|
|
||||||
|
ADS_Override_Strip,
|
||||||
|
ADS_Override_SoloStrip,
|
||||||
|
ADS_Override_AllRed,
|
||||||
|
ADS_Override_AllGreen,
|
||||||
|
ADS_Override_AllBlue,
|
||||||
|
|
||||||
|
ADS_Override_Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
global gs_const_string OverrideTypeStrings[] = {
|
||||||
|
LitString("Override_None"),
|
||||||
|
LitString("Override_Strip"),
|
||||||
|
LitString("Override_SoloStrip" ),
|
||||||
|
LitString("Override_AllRed" ),
|
||||||
|
LitString("Override_AllGreen" ),
|
||||||
|
LitString("Override_AllBlue" ),
|
||||||
|
LitString("Override_Count"),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct assembly_debug_state
|
||||||
|
{
|
||||||
|
override_type Override;
|
||||||
|
u32 TargetAssembly;
|
||||||
|
u32 TargetStrip;
|
||||||
|
pixel TargetColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AssemblyDebug_OverrideOutput(assembly_debug_state State, assembly_array Assemblies, led_system LedSystem)
|
||||||
|
{
|
||||||
|
if (State.Override == ADS_Override_None) return;
|
||||||
|
State.TargetColor = pixel{255,255,255};
|
||||||
|
|
||||||
|
assembly Assembly = Assemblies.Values[State.TargetAssembly];
|
||||||
|
led_buffer LedBuffer = LedSystem.Buffers[Assembly.LedBufferIndex];
|
||||||
|
|
||||||
|
switch (State.Override)
|
||||||
|
{
|
||||||
|
case ADS_Override_Strip:
|
||||||
|
{
|
||||||
|
v2_strip Strip = Assembly.Strips[State.TargetStrip];
|
||||||
|
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||||
|
{
|
||||||
|
u32 LedIdx = Strip.LedLUT[i];
|
||||||
|
LedBuffer.Colors[LedIdx] = State.TargetColor;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ADS_Override_SoloStrip:
|
||||||
|
{
|
||||||
|
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||||
|
{
|
||||||
|
v2_strip Strip = Assembly.Strips[s];
|
||||||
|
|
||||||
|
pixel Color = pixel{0,0,0};
|
||||||
|
if (s == State.TargetStrip)
|
||||||
|
{
|
||||||
|
Color = State.TargetColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||||
|
{
|
||||||
|
u32 LedIdx = Strip.LedLUT[i];
|
||||||
|
LedBuffer.Colors[LedIdx] = Color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ADS_Override_AllRed:
|
||||||
|
{
|
||||||
|
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||||
|
{
|
||||||
|
v2_strip Strip = Assembly.Strips[s];
|
||||||
|
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||||
|
{
|
||||||
|
u32 LedIdx = Strip.LedLUT[i];
|
||||||
|
LedBuffer.Colors[LedIdx] = pixel{255, 0, 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ADS_Override_AllGreen:
|
||||||
|
{
|
||||||
|
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||||
|
{
|
||||||
|
v2_strip Strip = Assembly.Strips[s];
|
||||||
|
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||||
|
{
|
||||||
|
u32 LedIdx = Strip.LedLUT[i];
|
||||||
|
LedBuffer.Colors[LedIdx] = pixel{0, 255, 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ADS_Override_AllBlue:
|
||||||
|
{
|
||||||
|
for (u32 s = 0; s < Assembly.StripCount; s++)
|
||||||
|
{
|
||||||
|
v2_strip Strip = Assembly.Strips[s];
|
||||||
|
for (u32 i = 0; i < Strip.LedCount; i++)
|
||||||
|
{
|
||||||
|
u32 LedIdx = Strip.LedLUT[i];
|
||||||
|
LedBuffer.Colors[LedIdx] = pixel{0, 0, 255};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ADS_Override_None:
|
||||||
|
{
|
||||||
|
}break;
|
||||||
|
|
||||||
|
InvalidDefaultCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (State.Override )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define FOLDHAUS_ASSEMBLY_DEBUG_H
|
||||||
|
#endif // FOLDHAUS_ASSEMBLY_DEBUG_H
|
|
@ -56,7 +56,7 @@ UART_DrawAll_Create(gs_memory_cursor* WriteCursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assemblies, led_system* LedSystem)
|
UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assemblies, led_system* LedSystem, gs_memory_arena* Transient)
|
||||||
{
|
{
|
||||||
uart_channel ChannelSettings = {0};
|
uart_channel ChannelSettings = {0};
|
||||||
ChannelSettings.ElementsCount = 3;
|
ChannelSettings.ElementsCount = 3;
|
||||||
|
@ -71,22 +71,88 @@ UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assembli
|
||||||
assembly Assembly = Assemblies.Values[AssemblyIdx];
|
assembly Assembly = Assemblies.Values[AssemblyIdx];
|
||||||
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex);
|
led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex);
|
||||||
|
|
||||||
u32 TotalBufferSize = MessageBaseSize * Assembly.StripCount; // SetChannelBuffer messages
|
struct strips_to_data_buffer
|
||||||
TotalBufferSize += MessageBaseSize; // DrawAll message
|
{
|
||||||
TotalBufferSize += ChannelSettings.ElementsCount * Assembly.LedCountTotal; // pixels * channels per pixel
|
gs_const_string ComPort;
|
||||||
|
u32* StripIndices;
|
||||||
|
u32 StripIndicesCount;
|
||||||
|
u32 StripIndicesCountMax;
|
||||||
|
|
||||||
|
u64 LedCount;
|
||||||
|
|
||||||
|
strips_to_data_buffer* Next;
|
||||||
|
};
|
||||||
|
|
||||||
addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, TotalBufferSize);
|
strips_to_data_buffer* BuffersNeededHead = 0;
|
||||||
AddressedDataBuffer_SetCOMPort(Buffer, Assembly.UARTComPort.ConstString);
|
strips_to_data_buffer* BuffersNeededTail = 0;
|
||||||
gs_memory_cursor WriteCursor = CreateMemoryCursor(Buffer->Data);
|
|
||||||
|
|
||||||
for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++)
|
for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++)
|
||||||
{
|
{
|
||||||
v2_strip StripAt = Assembly.Strips[StripIdx];
|
v2_strip StripAt = Assembly.Strips[StripIdx];
|
||||||
ChannelSettings.PixelsCount = StripAt.LedCount;
|
|
||||||
UART_SetChannelBuffer_Create(&WriteCursor, ChannelSettings, StripAt, *LedBuffer);
|
// If there is a buffer for this com port already created
|
||||||
|
// we use that
|
||||||
|
strips_to_data_buffer* BufferSelected = 0;
|
||||||
|
for (strips_to_data_buffer* At = BuffersNeededHead;
|
||||||
|
At!= 0;
|
||||||
|
At = At->Next)
|
||||||
|
{
|
||||||
|
if (StringsEqual(At->ComPort, StripAt.UARTAddr.ComPort.ConstString))
|
||||||
|
{
|
||||||
|
BufferSelected = At;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no existing buffer for this com port
|
||||||
|
// create a new one
|
||||||
|
if (!BufferSelected)
|
||||||
|
{
|
||||||
|
BufferSelected = PushStruct(Transient, strips_to_data_buffer);
|
||||||
|
*BufferSelected = {};
|
||||||
|
BufferSelected->ComPort = StripAt.UARTAddr.ComPort.ConstString;
|
||||||
|
// we don't know at this point how many indices per
|
||||||
|
// com port so just make enough room to fit all the strips
|
||||||
|
// if necessary
|
||||||
|
BufferSelected->StripIndicesCountMax = Assembly.StripCount;
|
||||||
|
BufferSelected->StripIndices = PushArray(Transient, u32, BufferSelected->StripIndicesCountMax);
|
||||||
|
BufferSelected->LedCount = 0;
|
||||||
|
BufferSelected->Next = 0;
|
||||||
|
|
||||||
|
SLLPushOrInit(BuffersNeededHead, BuffersNeededTail, BufferSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(BufferSelected->StripIndicesCount < BufferSelected->StripIndicesCountMax);
|
||||||
|
u32 Index = BufferSelected->StripIndicesCount++;
|
||||||
|
BufferSelected->StripIndices[Index] = StripIdx;
|
||||||
|
BufferSelected->LedCount += StripAt.LedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
UART_DrawAll_Create(&WriteCursor);
|
for (strips_to_data_buffer* At = BuffersNeededHead;
|
||||||
|
At!= 0;
|
||||||
|
At = At->Next)
|
||||||
|
{
|
||||||
|
u32 TotalBufferSize = MessageBaseSize * Assembly.StripCount; // SetChannelBuffer messages
|
||||||
|
TotalBufferSize += MessageBaseSize; // DrawAll message
|
||||||
|
TotalBufferSize += ChannelSettings.ElementsCount * At->LedCount; // pixels * channels per pixel
|
||||||
|
|
||||||
|
addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, TotalBufferSize);
|
||||||
|
gs_const_string ComPort = At->ComPort;
|
||||||
|
AddressedDataBuffer_SetCOMPort(Buffer, ComPort);
|
||||||
|
|
||||||
|
gs_memory_cursor WriteCursor = CreateMemoryCursor(Buffer->Data);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < At->StripIndicesCount; i++)
|
||||||
|
{
|
||||||
|
u32 StripIdx = At->StripIndices[i];
|
||||||
|
v2_strip StripAt = Assembly.Strips[StripIdx];
|
||||||
|
|
||||||
|
ChannelSettings.PixelsCount = StripAt.LedCount;
|
||||||
|
UART_SetChannelBuffer_Create(&WriteCursor, ChannelSettings, StripAt, *LedBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
UART_DrawAll_Create(&WriteCursor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ ClearAndPushPatterns(animation_pattern_array* Patterns)
|
||||||
Patterns_PushPattern(Patterns, Pattern_Spots);
|
Patterns_PushPattern(Patterns, Pattern_Spots);
|
||||||
Patterns_PushPattern(Patterns, Pattern_LighthouseRainbow);
|
Patterns_PushPattern(Patterns, Pattern_LighthouseRainbow);
|
||||||
Patterns_PushPattern(Patterns, Pattern_SmoothGrowRainbow);
|
Patterns_PushPattern(Patterns, Pattern_SmoothGrowRainbow);
|
||||||
|
Patterns_PushPattern(Patterns, Pattern_GrowAndFade);
|
||||||
}
|
}
|
||||||
|
|
||||||
RELOAD_STATIC_DATA(ReloadStaticData)
|
RELOAD_STATIC_DATA(ReloadStaticData)
|
||||||
|
@ -133,16 +134,20 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
State->Assemblies,
|
State->Assemblies,
|
||||||
&State->LedSystem,
|
&State->LedSystem,
|
||||||
State->Patterns,
|
State->Patterns,
|
||||||
State->Transient);
|
State->Transient,
|
||||||
|
State->UserData.Memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssemblyDebug_OverrideOutput(State->AssemblyDebugState,
|
||||||
|
State->Assemblies,
|
||||||
|
State->LedSystem);
|
||||||
|
|
||||||
// NOTE(pjs): Building data buffers to be sent out to the sculpture
|
// NOTE(pjs): Building data buffers to be sent out to the sculpture
|
||||||
// This array is used on the platform side to actually send the information
|
// This array is used on the platform side to actually send the information
|
||||||
assembly_array SACNAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaSACN, State->Transient);
|
assembly_array SACNAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaSACN, State->Transient);
|
||||||
assembly_array UARTAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaUART, State->Transient);
|
assembly_array UARTAssemblies = AssemblyArray_Filter(State->Assemblies, AssemblyFilter_OutputsViaUART, State->Transient);
|
||||||
SACN_BuildOutputData(&State->SACN, OutputData, SACNAssemblies, &State->LedSystem);
|
SACN_BuildOutputData(&State->SACN, OutputData, SACNAssemblies, &State->LedSystem);
|
||||||
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem);
|
UART_BuildOutputData(OutputData, UARTAssemblies, &State->LedSystem, State->Transient);
|
||||||
|
|
||||||
Editor_Render(State, Context, RenderBuffer);
|
Editor_Render(State, Context, RenderBuffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "engine/assembly/foldhaus_assembly.h"
|
#include "engine/assembly/foldhaus_assembly.h"
|
||||||
#include "engine/assembly/foldhaus_assembly_parser.cpp"
|
#include "engine/assembly/foldhaus_assembly_parser.cpp"
|
||||||
|
#include "engine/assembly/foldhaus_assembly_debug.h"
|
||||||
|
|
||||||
#include "engine/sacn/foldhaus_sacn.h"
|
#include "engine/sacn/foldhaus_sacn.h"
|
||||||
#include "engine/uart/foldhaus_uart.h"
|
#include "engine/uart/foldhaus_uart.h"
|
||||||
|
@ -51,6 +52,7 @@ struct app_state
|
||||||
streaming_acn SACN;
|
streaming_acn SACN;
|
||||||
led_system LedSystem;
|
led_system LedSystem;
|
||||||
assembly_array Assemblies;
|
assembly_array Assemblies;
|
||||||
|
assembly_debug_state AssemblyDebugState;
|
||||||
animation_system AnimationSystem;
|
animation_system AnimationSystem;
|
||||||
event_log* GlobalLog;
|
event_log* GlobalLog;
|
||||||
animation_pattern_array Patterns;
|
animation_pattern_array Patterns;
|
||||||
|
@ -65,411 +67,17 @@ struct app_state
|
||||||
ui_interface Interface;
|
ui_interface Interface;
|
||||||
panel_system PanelSystem;
|
panel_system PanelSystem;
|
||||||
panel* HotPanel;
|
panel* HotPanel;
|
||||||
|
|
||||||
|
// User Space
|
||||||
|
//
|
||||||
|
gs_data UserData;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void OpenColorPicker(app_state* State, v4* Address);
|
internal void OpenColorPicker(app_state* State, v4* Address);
|
||||||
|
|
||||||
#include "engine/assembly/foldhaus_assembly.cpp"
|
#include "engine/assembly/foldhaus_assembly.cpp"
|
||||||
|
|
||||||
// BEGIN TEMPORARY PATTERNS
|
#include "patterns/blumen_patterns.h"
|
||||||
internal void
|
|
||||||
TestPatternOne(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
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 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 LedPosition = Leds->Positions[LedIndex];
|
|
||||||
float PercentX = RemapClampedR32(LedPosition.x, -150.0f, 150.0f, 0.0f, 1.0f);
|
|
||||||
float PercentY = RemapClampedR32(LedPosition.y, -150.0f, 150.0f, 0.0f, 1.0f);
|
|
||||||
Leds->Colors[LedIndex].R = (u8)(PercentX * 255);
|
|
||||||
Leds->Colors[LedIndex].G = (u8)(PercentY * 255);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
TestPatternTwo(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
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 = 0; LedIndex < Leds->LedCount; 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, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
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 = 0; LedIndex < Leds->LedCount; 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 HSVToRGB (v4 In)
|
|
||||||
{
|
|
||||||
float Hue = In.x;
|
|
||||||
/*
|
|
||||||
while (Hue > 360.0f) { Hue -= 360.0f; }
|
|
||||||
while (Hue < 0.0f) { Hue += 360.0f; }
|
|
||||||
*/
|
|
||||||
Hue = ModR32(Hue, 360.0f);
|
|
||||||
if (Hue < 0) { Hue += 360.0f; }
|
|
||||||
if (Hue == MinR32) { Hue = 0; }
|
|
||||||
if (Hue == MaxR32) { Hue = 360; }
|
|
||||||
Assert(Hue >= 0 && Hue < 360);
|
|
||||||
|
|
||||||
float Sat = In.y;
|
|
||||||
float Value = In.z;
|
|
||||||
|
|
||||||
float hh, p, q, t, ff;
|
|
||||||
long i;
|
|
||||||
v4 Result = {};
|
|
||||||
Result.a = In.a;
|
|
||||||
|
|
||||||
if(Sat <= 0.0f) { // < is bogus, just shuts up warnings
|
|
||||||
Result.r = Value;
|
|
||||||
Result.g = Value;
|
|
||||||
Result.b = Value;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
hh = Hue;
|
|
||||||
if(hh >= 360.0f) hh = 0.0f;
|
|
||||||
hh /= 60.0f;
|
|
||||||
i = (long)hh;
|
|
||||||
ff = hh - i;
|
|
||||||
p = Value * (1.0f - Sat);
|
|
||||||
q = Value * (1.0f - (Sat * ff));
|
|
||||||
t = Value * (1.0f - (Sat * (1.0f - ff)));
|
|
||||||
|
|
||||||
switch(i) {
|
|
||||||
case 0:
|
|
||||||
{Result.r = Value;
|
|
||||||
Result.g = t;
|
|
||||||
Result.b = p;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
Result.r = q;
|
|
||||||
Result.g = Value;
|
|
||||||
Result.b = p;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
Result.r = p;
|
|
||||||
Result.g = Value;
|
|
||||||
Result.b = t;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
Result.r = p;
|
|
||||||
Result.g = q;
|
|
||||||
Result.b = Value;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
Result.r = t;
|
|
||||||
Result.g = p;
|
|
||||||
Result.b = Value;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
Result.r = Value;
|
|
||||||
Result.g = p;
|
|
||||||
Result.b = q;
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_HueShift(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
r32 Height = SinR32(Time) * 25;
|
|
||||||
|
|
||||||
r32 CycleLength = 5.0f;
|
|
||||||
r32 CycleProgress = FractR32(Time / CycleLength);
|
|
||||||
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 Pos = Leds->Positions[LedIndex];
|
|
||||||
r32 Dist = Pos.y - Height;
|
|
||||||
|
|
||||||
v4 HSV = { (ModR32(Dist, 25) / 25) * 360, 1, 1, 1 };
|
|
||||||
v4 RGB = HSVToRGB(HSV);
|
|
||||||
|
|
||||||
u8 R = (u8)(RGB.x * 255);
|
|
||||||
u8 G = (u8)(RGB.y * 255);
|
|
||||||
u8 B = (u8)(RGB.z * 255);
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex].R = R;
|
|
||||||
Leds->Colors[LedIndex].G = G;
|
|
||||||
Leds->Colors[LedIndex].B = B;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal pixel
|
|
||||||
V4ToRGBPixel(v4 C)
|
|
||||||
{
|
|
||||||
pixel Result = {};
|
|
||||||
Result.R = (u8)(C.x * 255);
|
|
||||||
Result.G = (u8)(C.y * 255);
|
|
||||||
Result.B = (u8)(C.z * 255);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_HueFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
r32 HueBase = ModR32(Time * 50, 360);
|
|
||||||
|
|
||||||
r32 CycleLength = 5.0f;
|
|
||||||
r32 CycleProgress = FractR32(Time / CycleLength);
|
|
||||||
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
|
||||||
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 Pos = Leds->Positions[LedIndex];
|
|
||||||
r32 Hue = HueBase + Pos.y + Pos.x;
|
|
||||||
v4 HSV = { Hue, 1, 1, 1 };
|
|
||||||
v4 RGB = HSVToRGB(HSV);
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_AllGreen(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
|
||||||
u32 I = LedIndex + 1;
|
|
||||||
Leds->Colors[LedIndex] = {};
|
|
||||||
if (I % 3 == 0)
|
|
||||||
{
|
|
||||||
Leds->Colors[LedIndex].R = 255;
|
|
||||||
}
|
|
||||||
else if (I % 3 == 1)
|
|
||||||
{
|
|
||||||
Leds->Colors[LedIndex].G = 255;
|
|
||||||
}
|
|
||||||
else if (I % 3 == 2)
|
|
||||||
{
|
|
||||||
Leds->Colors[LedIndex].B = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal r32
|
|
||||||
PatternHash(r32 Seed)
|
|
||||||
{
|
|
||||||
return FractR32(Seed * 17.0 * FractR32(Seed * 0.3183099));
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_Spots(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
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 = 0; LedIndex < Leds->LedCount; 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, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
|
||||||
v2 Vector = v2{
|
|
||||||
Leds->Positions[LedIndex].x,
|
|
||||||
Leds->Positions[LedIndex].z
|
|
||||||
};
|
|
||||||
Vector = V2Normalize(Vector);
|
|
||||||
|
|
||||||
r32 Angle = V2Dot(RefVector, Vector);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
r32 Fade = RemapR32(Angle, -1, 1, 0, 1);
|
|
||||||
Leds->Colors[LedIndex].R = (u8)(Fade * 255);
|
|
||||||
Leds->Colors[LedIndex].G = (u8)(Fade * 255);
|
|
||||||
Leds->Colors[LedIndex].B = (u8)(Fade * 255);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
v4 HSV = { (Angle * 30) + (Time * 10) + Leds->Positions[LedIndex].y, 1, 1, 1 };
|
|
||||||
v4 RGB = HSVToRGB(HSV);
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal r32
|
|
||||||
Smoothstep(r32 T)
|
|
||||||
{
|
|
||||||
r32 Result = (T * T * (3 - (2 * T)));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Pattern_SmoothGrowRainbow(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient)
|
|
||||||
{
|
|
||||||
r32 FillCycleTime = ModR32(Time, 7.0f) / 7.0f;
|
|
||||||
r32 ColorCycleTime = ModR32(Time, 21.0f) / 21.0f;
|
|
||||||
|
|
||||||
//v4 HSV = { ColorCycleTime * 360, 1, 1, 1 };
|
|
||||||
//v4 RGB0 = HSVToRGB(HSV);
|
|
||||||
//HSV.x += ;
|
|
||||||
//v4 RGB1 = HSVToRGB(HSV);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
|
||||||
{
|
|
||||||
v4 P = Leds->Positions[LedIndex];
|
|
||||||
|
|
||||||
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB0);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// END TEMPORARY PATTERNS
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
EndCurrentOperationMode(app_state* State)
|
EndCurrentOperationMode(app_state* State)
|
||||||
|
@ -485,6 +93,7 @@ EndCurrentOperationMode(app_state* State)
|
||||||
#include "editor/panels/foldhaus_panel_dmx_view.h"
|
#include "editor/panels/foldhaus_panel_dmx_view.h"
|
||||||
#include "editor/panels/foldhaus_panel_animation_timeline.h"
|
#include "editor/panels/foldhaus_panel_animation_timeline.h"
|
||||||
#include "editor/panels/foldhaus_panel_hierarchy.h"
|
#include "editor/panels/foldhaus_panel_hierarchy.h"
|
||||||
|
#include "editor/panels/foldhaus_panel_assembly_debug.h"
|
||||||
|
|
||||||
|
|
||||||
#include "editor/panels/foldhaus_panel_types.cpp"
|
#include "editor/panels/foldhaus_panel_types.cpp"
|
||||||
|
|
|
@ -148,7 +148,7 @@ typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint);
|
||||||
|
|
||||||
// Worker Threads
|
// Worker Threads
|
||||||
|
|
||||||
#define PLATFORM_THREAD_COUNT 0
|
#define PLATFORM_THREAD_COUNT 3
|
||||||
|
|
||||||
RESET_WORK_QUEUE(ResetWorkQueue)
|
RESET_WORK_QUEUE(ResetWorkQueue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1513,11 +1513,35 @@ ui_EndMousePopup(ui_interface* Interface)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
internal void
|
||||||
|
ui_BeginLabelRow(ui_interface* Interface, gs_string Label, u32 Count = 2)
|
||||||
|
{
|
||||||
|
ui_BeginRow(Interface, Count);
|
||||||
|
ui_Label(Interface, Label);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool
|
||||||
|
ui_LabeledToggle(ui_interface* Interface, gs_string Label, bool Value)
|
||||||
|
{
|
||||||
|
ui_BeginLabelRow(Interface, Label);
|
||||||
|
bool Result = ui_Toggle(Interface, Label, Value);
|
||||||
|
ui_EndRow(Interface);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal u64
|
||||||
|
ui_LabeledTextEntryU64(ui_interface* Interface, gs_string Label, u32 Value)
|
||||||
|
{
|
||||||
|
ui_BeginLabelRow(Interface, Label);
|
||||||
|
u64 Result = ui_TextEntryU64(Interface, Label, Value);
|
||||||
|
ui_EndRow(Interface);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal bool
|
internal bool
|
||||||
ui_BeginLabeledDropdown(ui_interface* Interface, gs_string Label, gs_string DropdownValue)
|
ui_BeginLabeledDropdown(ui_interface* Interface, gs_string Label, gs_string DropdownValue)
|
||||||
{
|
{
|
||||||
ui_BeginRow(Interface, 2);
|
ui_BeginLabelRow(Interface, Label);
|
||||||
ui_Label(Interface, Label);
|
|
||||||
return ui_BeginDropdown(Interface, DropdownValue);
|
return ui_BeginDropdown(Interface, DropdownValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,395 @@
|
||||||
|
//
|
||||||
|
// File: blumen_patterns.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2021-01-15
|
||||||
|
//
|
||||||
|
#ifndef BLUMEN_PATTERNS_H
|
||||||
|
|
||||||
|
internal void
|
||||||
|
TestPatternOne(led_buffer* Leds, 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, 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 = 0; LedIndex < Leds->LedCount; 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, 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 = 0; LedIndex < Leds->LedCount; 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 HSVToRGB (v4 In)
|
||||||
|
{
|
||||||
|
float Hue = In.x;
|
||||||
|
/*
|
||||||
|
while (Hue > 360.0f) { Hue -= 360.0f; }
|
||||||
|
while (Hue < 0.0f) { Hue += 360.0f; }
|
||||||
|
*/
|
||||||
|
Hue = ModR32(Hue, 360.0f);
|
||||||
|
if (Hue < 0) { Hue += 360.0f; }
|
||||||
|
if (Hue == MinR32) { Hue = 0; }
|
||||||
|
if (Hue == MaxR32) { Hue = 360; }
|
||||||
|
Assert(Hue >= 0 && Hue < 360);
|
||||||
|
|
||||||
|
float Sat = In.y;
|
||||||
|
float Value = In.z;
|
||||||
|
|
||||||
|
float hh, p, q, t, ff;
|
||||||
|
long i;
|
||||||
|
v4 Result = {};
|
||||||
|
Result.a = In.a;
|
||||||
|
|
||||||
|
if(Sat <= 0.0f) { // < is bogus, just shuts up warnings
|
||||||
|
Result.r = Value;
|
||||||
|
Result.g = Value;
|
||||||
|
Result.b = Value;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
hh = Hue;
|
||||||
|
if(hh >= 360.0f) hh = 0.0f;
|
||||||
|
hh /= 60.0f;
|
||||||
|
i = (long)hh;
|
||||||
|
ff = hh - i;
|
||||||
|
p = Value * (1.0f - Sat);
|
||||||
|
q = Value * (1.0f - (Sat * ff));
|
||||||
|
t = Value * (1.0f - (Sat * (1.0f - ff)));
|
||||||
|
|
||||||
|
switch(i) {
|
||||||
|
case 0:
|
||||||
|
{Result.r = Value;
|
||||||
|
Result.g = t;
|
||||||
|
Result.b = p;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
Result.r = q;
|
||||||
|
Result.g = Value;
|
||||||
|
Result.b = p;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
Result.r = p;
|
||||||
|
Result.g = Value;
|
||||||
|
Result.b = t;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
Result.r = p;
|
||||||
|
Result.g = q;
|
||||||
|
Result.b = Value;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
Result.r = t;
|
||||||
|
Result.g = p;
|
||||||
|
Result.b = Value;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Result.r = Value;
|
||||||
|
Result.g = p;
|
||||||
|
Result.b = q;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_HueShift(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
r32 Height = SinR32(Time) * 25;
|
||||||
|
|
||||||
|
r32 CycleLength = 5.0f;
|
||||||
|
r32 CycleProgress = FractR32(Time / CycleLength);
|
||||||
|
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
||||||
|
|
||||||
|
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||||
|
{
|
||||||
|
v4 Pos = Leds->Positions[LedIndex];
|
||||||
|
r32 Dist = Pos.y - Height;
|
||||||
|
|
||||||
|
v4 HSV = { (ModR32(Dist, 25) / 25) * 360, 1, 1, 1 };
|
||||||
|
v4 RGB = HSVToRGB(HSV);
|
||||||
|
|
||||||
|
u8 R = (u8)(RGB.x * 255);
|
||||||
|
u8 G = (u8)(RGB.y * 255);
|
||||||
|
u8 B = (u8)(RGB.z * 255);
|
||||||
|
|
||||||
|
Leds->Colors[LedIndex].R = R;
|
||||||
|
Leds->Colors[LedIndex].G = G;
|
||||||
|
Leds->Colors[LedIndex].B = B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal pixel
|
||||||
|
V4ToRGBPixel(v4 C)
|
||||||
|
{
|
||||||
|
pixel Result = {};
|
||||||
|
Result.R = (u8)(C.x * 255);
|
||||||
|
Result.G = (u8)(C.y * 255);
|
||||||
|
Result.B = (u8)(C.z * 255);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_HueFade(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
r32 HueBase = ModR32(Time * 50, 360);
|
||||||
|
|
||||||
|
r32 CycleLength = 5.0f;
|
||||||
|
r32 CycleProgress = FractR32(Time / CycleLength);
|
||||||
|
r32 CycleBlend = (SinR32(Time) * .5f) + .5f;
|
||||||
|
|
||||||
|
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||||
|
{
|
||||||
|
v4 Pos = Leds->Positions[LedIndex];
|
||||||
|
r32 Hue = HueBase + Pos.y + Pos.x;
|
||||||
|
v4 HSV = { Hue, 1, 1, 1 };
|
||||||
|
v4 RGB = HSVToRGB(HSV);
|
||||||
|
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_AllGreen(led_buffer* Leds, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||||
|
{
|
||||||
|
u32 I = LedIndex + 1;
|
||||||
|
Leds->Colors[LedIndex] = {};
|
||||||
|
if (I % 3 == 0)
|
||||||
|
{
|
||||||
|
Leds->Colors[LedIndex].R = 255;
|
||||||
|
}
|
||||||
|
else if (I % 3 == 1)
|
||||||
|
{
|
||||||
|
Leds->Colors[LedIndex].G = 255;
|
||||||
|
}
|
||||||
|
else if (I % 3 == 2)
|
||||||
|
{
|
||||||
|
Leds->Colors[LedIndex].B = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
PatternHash(r32 Seed)
|
||||||
|
{
|
||||||
|
return FractR32(Seed * 17.0 * FractR32(Seed * 0.3183099));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_Spots(led_buffer* Leds, 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 = 0; LedIndex < Leds->LedCount; 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, assembly Assembly, r32 Time, gs_memory_arena* Transient, u8* UserData)
|
||||||
|
{
|
||||||
|
v2 RefVector = V2Normalize(v2{ SinR32(Time), CosR32(Time) });
|
||||||
|
for (u32 LedIndex = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||||
|
{
|
||||||
|
v2 Vector = v2{
|
||||||
|
Leds->Positions[LedIndex].x,
|
||||||
|
Leds->Positions[LedIndex].z
|
||||||
|
};
|
||||||
|
Vector = V2Normalize(Vector);
|
||||||
|
|
||||||
|
r32 Angle = V2Dot(RefVector, Vector);
|
||||||
|
|
||||||
|
v4 HSV = { (Angle * 30) + (Time * 10) + Leds->Positions[LedIndex].y, 1, 1, 1 };
|
||||||
|
v4 RGB = HSVToRGB(HSV);
|
||||||
|
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(RGB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
Smoothstep(r32 T)
|
||||||
|
{
|
||||||
|
r32 Result = (T * T * (3 - (2 * T)));
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Pattern_SmoothGrowRainbow(led_buffer* Leds, 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, 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 = 0; LedIndex < Leds->LedCount; LedIndex++)
|
||||||
|
{
|
||||||
|
v4 P = Leds->Positions[LedIndex];
|
||||||
|
|
||||||
|
v4 RgbFaded = v4{};
|
||||||
|
if (P.y < RefHeight)
|
||||||
|
{
|
||||||
|
RgbFaded = RGB * RefBrightness;
|
||||||
|
}
|
||||||
|
Leds->Colors[LedIndex] = V4ToRGBPixel(RgbFaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BLUMEN_PATTERNS_H
|
||||||
|
#endif // BLUMEN_PATTERNS_H
|
|
@ -371,64 +371,56 @@ Win32Realloc(u8* Buf, s32 OldSize, s32 NewSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Win32_SendAddressedDataBuffers(gs_thread_context Context, addressed_data_buffer_list OutputData)
|
Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer* BufferAt)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
u32 BuffersSent = 0;
|
u32 BuffersSent = 0;
|
||||||
u32 DataSizeSent = 0;
|
u32 DataSizeSent = 0;
|
||||||
|
|
||||||
for (addressed_data_buffer* BufferAt = OutputData.Root;
|
switch(BufferAt->AddressType)
|
||||||
BufferAt != 0;
|
|
||||||
BufferAt = BufferAt->Next)
|
|
||||||
{
|
{
|
||||||
switch(BufferAt->AddressType)
|
case AddressType_NetworkIP:
|
||||||
{
|
{
|
||||||
case AddressType_NetworkIP:
|
Win32Socket_SendTo(BufferAt->SendSocket,
|
||||||
|
BufferAt->V4SendAddress,
|
||||||
|
BufferAt->SendPort,
|
||||||
|
(const char*)BufferAt->Memory,
|
||||||
|
BufferAt->MemorySize,
|
||||||
|
0);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case AddressType_ComPort:
|
||||||
|
{
|
||||||
|
if (BufferAt->ComPort.Length > 0)
|
||||||
{
|
{
|
||||||
Win32Socket_SendTo(BufferAt->SendSocket,
|
HANDLE SerialPort = Win32SerialArray_GetOrOpen(BufferAt->ComPort, 2000000, 8, NOPARITY, 1);
|
||||||
BufferAt->V4SendAddress,
|
if (SerialPort != INVALID_HANDLE_VALUE)
|
||||||
BufferAt->SendPort,
|
|
||||||
(const char*)BufferAt->Memory,
|
|
||||||
BufferAt->MemorySize,
|
|
||||||
0);
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case AddressType_ComPort:
|
|
||||||
{
|
|
||||||
if (BufferAt->ComPort.Length > 0)
|
|
||||||
{
|
{
|
||||||
HANDLE SerialPort = Win32SerialArray_GetOrOpen(BufferAt->ComPort, 2000000, 8, NOPARITY, 1);
|
if (Win32SerialPort_Write(SerialPort, BufferAt->Data))
|
||||||
if (SerialPort != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
if (Win32SerialPort_Write(SerialPort, BufferAt->Data))
|
BuffersSent += 1;
|
||||||
{
|
DataSizeSent += BufferAt->Data.Size;
|
||||||
BuffersSent += 1;
|
|
||||||
DataSizeSent += BufferAt->Data.Size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
OutputDebugStringA("Skipping data buffer because its COM Port isn't set");
|
{
|
||||||
}
|
#if 0
|
||||||
}break;
|
OutputDebugStringA("Skipping data buffer because its COM Port isn't set");
|
||||||
|
#endif
|
||||||
InvalidDefaultCase;
|
}
|
||||||
}
|
}break;
|
||||||
|
|
||||||
|
InvalidDefaultCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_string OutputStr = AllocatorAllocString(Context.Allocator, 256);
|
|
||||||
PrintF(&OutputStr, "Buffers Sent: %d | Size Sent: %d\n", BuffersSent, DataSizeSent);
|
|
||||||
NullTerminate(&OutputStr);
|
|
||||||
OutputDebugStringA(OutputStr.Str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
Win32_SendAddressedDataBuffers_Job(gs_thread_context Context, gs_data Arg)
|
Win32_SendAddressedDataBuffer_Job(gs_thread_context Context, gs_data Arg)
|
||||||
{
|
{
|
||||||
addressed_data_buffer_list* OutputData = (addressed_data_buffer_list*)Arg.Memory;
|
addressed_data_buffer* OutputData = (addressed_data_buffer*)Arg.Memory;
|
||||||
Win32_SendAddressedDataBuffers(Context, *OutputData);
|
Win32_SendAddressedDataBuffer(Context, OutputData);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
@ -571,10 +563,15 @@ WinMain (
|
||||||
|
|
||||||
if (true)
|
if (true)
|
||||||
{
|
{
|
||||||
gs_data ProcArg = {};
|
for (addressed_data_buffer* At = OutputData.Root;
|
||||||
ProcArg.Memory = (u8*)&OutputData;
|
At != 0;
|
||||||
ProcArg.Size = sizeof(OutputData);
|
At = At->Next)
|
||||||
Win32PushWorkOnQueue(&Win32WorkQueue.WorkQueue, Win32_SendAddressedDataBuffers_Job, ProcArg, ConstString("Send UART Data"));
|
{
|
||||||
|
gs_data ProcArg = {};
|
||||||
|
ProcArg.Memory = (u8*)At;
|
||||||
|
ProcArg.Size = sizeof(addressed_data_buffer);
|
||||||
|
Win32PushWorkOnQueue(&Win32WorkQueue.WorkQueue, Win32_SendAddressedDataBuffer_Job, ProcArg, ConstString("Send UART Data"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mouse_Advance(&Context);
|
Mouse_Advance(&Context);
|
||||||
|
@ -583,7 +580,7 @@ WinMain (
|
||||||
SwapBuffers(DeviceContext);
|
SwapBuffers(DeviceContext);
|
||||||
ReleaseDC(MainWindow.Handle, DeviceContext);
|
ReleaseDC(MainWindow.Handle, DeviceContext);
|
||||||
|
|
||||||
//Win32DoQueueWorkUntilDone(&WorkQueue, Context.ThreadContext);
|
Win32DoQueueWorkUntilDone(&Win32WorkQueue.WorkQueue, Context.ThreadContext);
|
||||||
|
|
||||||
s64 FinishedWorkTime = GetWallClock();
|
s64 FinishedWorkTime = GetWallClock();
|
||||||
r32 SecondsElapsed = GetSecondsElapsed(LastFrameEnd, FinishedWorkTime, PerformanceCountFrequency);
|
r32 SecondsElapsed = GetSecondsElapsed(LastFrameEnd, FinishedWorkTime, PerformanceCountFrequency);
|
||||||
|
|
|
@ -175,7 +175,7 @@ int main(int ArgCount, char** Args)
|
||||||
100,
|
100,
|
||||||
v3{0, 0, 0},
|
v3{0, 0, 0},
|
||||||
69,
|
69,
|
||||||
ComPort);
|
"");
|
||||||
|
|
||||||
u32 StemChannels[] = { FSC(2, 1), FSC(2, 2), FSC(2, 3), FSC(2, 4), FSC(2, 5), FSC(2, 6) };
|
u32 StemChannels[] = { FSC(2, 1), FSC(2, 2), FSC(2, 3), FSC(2, 4), FSC(2, 5), FSC(2, 6) };
|
||||||
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) };
|
||||||
|
@ -189,23 +189,24 @@ int main(int ArgCount, char** Args)
|
||||||
F0.BloomInnerChannels = BloomInnerChannels;
|
F0.BloomInnerChannels = BloomInnerChannels;
|
||||||
BuildFlower(&OutputBuffer, F0);
|
BuildFlower(&OutputBuffer, F0);
|
||||||
|
|
||||||
/*
|
|
||||||
flower_desc F1 = {};
|
flower_desc F1 = {};
|
||||||
F1.Pos = v3{0, 0, 0};
|
F1.Pos = v3{0, 0, 0};
|
||||||
|
F1.ComPort = "\\\\.\\COM9";
|
||||||
F1.FlowerTagValue = "center";
|
F1.FlowerTagValue = "center";
|
||||||
F1.StemChannels = StemChannels;
|
F1.StemChannels = StemChannels;
|
||||||
F1.BloomInnerChannels = BloomInnerChannels;
|
F1.BloomInnerChannels = BloomInnerChannels;
|
||||||
F1.BloomOuterChannels = BloomOuterChannels;
|
F1.BloomOuterChannels = BloomOuterChannels;
|
||||||
BuildFlower(&OutputBuffer, F1);
|
BuildFlower(&OutputBuffer, F1);
|
||||||
|
|
||||||
flower_desc F2 = {};
|
/*
|
||||||
F2.Pos = v3{1, 0, 0};
|
flower_desc F2 = {};
|
||||||
F2.FlowerTagValue = "right";
|
F2.Pos = v3{1, 0, 0};
|
||||||
F2.StemChannels = StemChannels;
|
F2.FlowerTagValue = "right";
|
||||||
F2.BloomInnerChannels = BloomInnerChannels;
|
F2.StemChannels = StemChannels;
|
||||||
F2.BloomOuterChannels = BloomOuterChannels;
|
F2.BloomInnerChannels = BloomInnerChannels;
|
||||||
BuildFlower(&OutputBuffer, F2);
|
F2.BloomOuterChannels = BloomOuterChannels;
|
||||||
*/
|
BuildFlower(&OutputBuffer, F2);
|
||||||
|
*/
|
||||||
|
|
||||||
printf("%.*s\n", (u32)OutputBuffer.Length, OutputBuffer.Str);
|
printf("%.*s\n", (u32)OutputBuffer.Length, OutputBuffer.Str);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,11 @@ WriteAssemblyUARTOpen(gs_string* Buffer, char* Name, u32 Scale, v3 Center, u32 S
|
||||||
WriteIndented(Buffer, 0, "assembly_center: (%f, %f, %f);\n", Center.x, Center.y, Center.z);
|
WriteIndented(Buffer, 0, "assembly_center: (%f, %f, %f);\n", Center.x, Center.y, Center.z);
|
||||||
WriteIndented(Buffer, 0, "led_strip_count: %d;\n", StripCount);
|
WriteIndented(Buffer, 0, "led_strip_count: %d;\n", StripCount);
|
||||||
WriteIndented(Buffer, 0, "output_mode: \"UART\";\n");
|
WriteIndented(Buffer, 0, "output_mode: \"UART\";\n");
|
||||||
WriteIndented(Buffer, 0, "com_port: \"%s\";\n", ComPort);
|
|
||||||
|
if (ComPort)
|
||||||
|
{
|
||||||
|
WriteIndented(Buffer, 0, "com_port: \"%s\";\n", ComPort);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// File: test_motor_header.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2021-01-14
|
||||||
|
//
|
||||||
|
#ifndef TEST_MOTOR_HEADER_H
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 MotorOnePos;
|
||||||
|
u8 MotorTwoPos;
|
||||||
|
u8 MotorThreePos;
|
||||||
|
} typedef packet;
|
||||||
|
|
||||||
|
static packet
|
||||||
|
UnpackPacket
|
||||||
|
|
||||||
|
#define TEST_MOTOR_HEADER_H
|
||||||
|
#endif // TEST_MOTOR_HEADER_H
|
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// File: test_sound_interface_packet.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2021-01-14
|
||||||
|
//
|
||||||
|
#ifndef TEST_SOUND_INTERFACE_PACKET_H
|
||||||
|
|
||||||
|
enum selectable_patterns
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u8 PrimaryColor[3];
|
||||||
|
u8 SecondaryColor[3];
|
||||||
|
u32 PatternIndex; // Set via selectable_patterns
|
||||||
|
u8 Speed; //
|
||||||
|
} sound_interface_packet;
|
||||||
|
|
||||||
|
// expects V to be in the range -1:1
|
||||||
|
u8 FloatToSpeed (float V)
|
||||||
|
{
|
||||||
|
u8 Result = (u8)(((V + 1) / 2) * 255);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define TEST_SOUND_INTERFACE_PACKET_H
|
||||||
|
#endif // TEST_SOUND_INTERFACE_PACKET_H
|
Loading…
Reference in New Issue