Lotta work on panels geting animation and sculpture view more up to scratch. Deleted a bunch of now obsolete files.

This commit is contained in:
Peter Slattery 2019-12-28 10:51:47 -08:00
parent 76d27e3b57
commit d112b01e79
16 changed files with 547 additions and 723 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -1,9 +0,0 @@
FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlock)
{
if (AnimationBlockHandleIsValid(State->SelectedAnimationBlockHandle))
{
RemoveAnimationBlock(State->SelectedAnimationBlockHandle, &State->AnimationSystem);
State->SelectedAnimationBlockHandle = {0};
}
}

View File

@ -83,11 +83,11 @@ DrawPanelFooter(Panel, RenderBuffer, FooterMin, FooterMax, State->Interface, Mou
} }
internal v4 internal v4
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, r32 WindowWidth, r32 WindowHeight) MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds)
{ {
DEBUG_TRACK_SCOPE(MouseToWorldRay); DEBUG_TRACK_SCOPE(MouseToWorldRay);
r32 X = ((2.0f * MouseX) / WindowWidth) - 1; r32 X = ((2.0f * MouseX) / Width(WindowBounds)) - 1;
r32 Y = ((2.0f * MouseY) / WindowHeight) - 1; r32 Y = ((2.0f * MouseY) / Height(WindowBounds)) - 1;
v4 ScreenPos = v4{X, Y, -1, 1}; v4 ScreenPos = v4{X, Y, -1, 1};
@ -147,12 +147,6 @@ RELOAD_STATIC_DATA(ReloadStaticData)
GlobalDebugServices = DebugServices; GlobalDebugServices = DebugServices;
GSAlloc = Alloc; GSAlloc = Alloc;
GSFree = Free; GSFree = Free;
if (State->DefaultInputCommandRegistry.Size > 0)
{
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_U, Command_Began, KeyCode_Invalid, OpenUniverseView);
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_X, Command_Ended, KeyCode_Invalid, DeleteAnimationBlock);
}
} }
INITIALIZE_APPLICATION(InitializeApplication) INITIALIZE_APPLICATION(InitializeApplication)
@ -165,8 +159,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->Transient.Alloc = (gs_memory_alloc*)Context.PlatformAlloc; State->Transient.Alloc = (gs_memory_alloc*)Context.PlatformAlloc;
State->Transient.Realloc = (gs_memory_realloc*)Context.PlatformRealloc; State->Transient.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
InitializeInputCommandRegistry(&State->DefaultInputCommandRegistry, 32, &State->Permanent);
s32 CommandQueueSize = 32; s32 CommandQueueSize = 32;
command_queue_entry* CommandQueueMemory = PushArray(&State->Permanent, command_queue_entry* CommandQueueMemory = PushArray(&State->Permanent,
command_queue_entry, command_queue_entry,
@ -223,7 +215,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
} }
State->Interface.Font = Font; State->Interface.Font = Font;
State->Font = Font;
Font->BitmapTextureHandle = Context.PlatformGetGPUTextureHandle(Font->BitmapMemory, Font->BitmapTextureHandle = Context.PlatformGetGPUTextureHandle(Font->BitmapMemory,
Font->BitmapWidth, Font->BitmapHeight); Font->BitmapWidth, Font->BitmapHeight);
@ -246,7 +237,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE; State->NetworkProtocolHeaderSize = STREAM_HEADER_SIZE;
State->Camera.FieldOfView = DegreesToRadians(45.0f); State->Camera.FieldOfView = DegreesToRadians(45.0f);
State->Camera.AspectRatio = (r32)Context.WindowWidth / (r32)Context.WindowHeight; State->Camera.AspectRatio = AspectRatio(State->WindowBounds);
State->Camera.Near = 1.0f; State->Camera.Near = 1.0f;
State->Camera.Far = 100.0f; State->Camera.Far = 100.0f;
State->Camera.Position = v3{0, 0, -250}; State->Camera.Position = v3{0, 0, -250};
@ -273,7 +264,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->Modes.Arena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc; State->Modes.Arena.Realloc = (gs_memory_realloc*)Context.PlatformRealloc;
State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly; State->Modes.Arena.FindAddressRule = FindAddress_InLastBufferOnly;
{ // MODES PLAYGROUND { // Animation PLAYGROUND
InitializeAnimationSystem(&State->AnimationSystem); InitializeAnimationSystem(&State->AnimationSystem);
State->AnimationSystem.SecondsPerFrame = 1.f / 24.f; State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
@ -294,23 +285,33 @@ State->AnimationSystem.SecondsPerFrame = 1.f / 24.f;
} // End Animation Playground } // End Animation Playground
{ // Panels Playground
InitializePanelLayout(&State->PanelLayout); InitializePanelLayout(&State->PanelLayout);
panel* Panel = TakeNewPanel(&State->PanelLayout); panel* Panel = TakeNewPanel(&State->PanelLayout);
SetPanelDefinition(Panel, 0); SetPanelDefinition(Panel, 0);
} // End Panels Playground
} }
internal void internal void
HandleInput (app_state* State, input_queue InputQueue, mouse_state Mouse) HandleInput (app_state* State, rect WindowBounds, input_queue InputQueue, mouse_state Mouse)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
input_command_registry ActiveCommands = State->DefaultInputCommandRegistry; input_command_registry ActiveCommands = {};
if (State->Modes.ActiveModesCount > 0) if (State->Modes.ActiveModesCount > 0)
{ {
ActiveCommands = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands; ActiveCommands = State->Modes.ActiveModes[State->Modes.ActiveModesCount - 1].Commands;
} }
else
{
panel_and_bounds PanelWithMouseOverIt = GetPanelContainingPoint(Mouse.Pos, &State->PanelLayout, WindowBounds);
if (!PanelWithMouseOverIt.Panel) { return; }
panel_definition PanelDefinition = GlobalPanelDefs[PanelWithMouseOverIt.Panel->PanelDefinitionIndex];
if (!PanelDefinition.InputCommands) { return; }
ActiveCommands.Commands = PanelDefinition.InputCommands;
ActiveCommands.Size = sizeof(*PanelDefinition.InputCommands) / sizeof(PanelDefinition.InputCommands[0]);
ActiveCommands.Used = ActiveCommands.Size;
}
for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++) for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++)
{ {
@ -395,6 +396,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
app_state* State = (app_state*)Context.MemoryBase; app_state* State = (app_state*)Context.MemoryBase;
State->WindowBounds = Context.WindowBounds;
// NOTE(Peter): We do this at the beginning because all the render commands are stored in Transient, // NOTE(Peter): We do this at the beginning because all the render commands are stored in Transient,
// and need to persist beyond the end of the UpdateAndRender call. In the release version, we won't // and need to persist beyond the end of the UpdateAndRender call. In the release version, we won't
@ -402,7 +404,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
// incorrect to clear the arena, and then access the memory later. // incorrect to clear the arena, and then access the memory later.
ClearArena(&State->Transient); ClearArena(&State->Transient);
HandleInput(State, InputQueue, Mouse); HandleInput(State, State->WindowBounds, InputQueue, Mouse);
if (State->AnimationSystem.TimelineShouldAdvance) { if (State->AnimationSystem.TimelineShouldAdvance) {
State->AnimationSystem.Time += Context.DeltaTime; State->AnimationSystem.Time += Context.DeltaTime;
@ -484,77 +486,11 @@ s32 CurrentFrame = (s32)(State->AnimationSystem.Time / State->AnimationSystem.Se
} }
} }
PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHeight); PushRenderOrthographic(RenderBuffer, 0, 0, Width(State->WindowBounds), Height(State->WindowBounds));
PushRenderClearScreen(RenderBuffer); PushRenderClearScreen(RenderBuffer);
v2 WindowMin = v2{0, 0}; HandleMousePanelInteraction(&State->PanelLayout, State->WindowBounds, Mouse);
v2 WindowMax = v2{Context.WindowWidth, Context.WindowHeight};
HandleMousePanelInteraction(&State->PanelLayout, WindowMin, WindowMax, Mouse);
DrawAllPanels(State->PanelLayout, WindowMin, WindowMax, RenderBuffer, State->Interface, Mouse, State, Context);
////////////////////////////////
// Render Assembly
///////////////////////////////
if (Context.WindowIsVisible)
{
#if 0
///////////////////////////////////////
// Interface
//////////////////////////////////////
DEBUG_TRACK_SCOPE(DrawInterface);
PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHeight);
///////////////////////////////////////
// Menu Bar
//////////////////////////////////////
r32 TopBarHeight = 40;
{
panel_result TopBarPanel = EvaluatePanel(RenderBuffer,
v2{0, Context.WindowHeight - TopBarHeight},
v2{Context.WindowWidth, Context.WindowHeight},
0, State->Interface);
v2 ButtonDim = v2{200, (r32)NewLineYOffset(*State->Interface.Font) + 10};
v2 ButtonPos = v2{State->Interface.Margin.x, Context.WindowHeight - (ButtonDim.y + 10)};
button_result LoadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
MakeStringLiteral("Load Assembly"),
State->Interface, Mouse);
string InterfaceString = MakeString(PushArray(&State->Transient, char, 256), 256);
for (s32 i = 0; i < State->ActiveAssemblyIndecies.Used; i++)
{
array_entry_handle AssemblyHandle = *GetElementAtIndex(i, State->ActiveAssemblyIndecies);
assembly Assembly = *GetElementWithHandle(AssemblyHandle, State->AssemblyList);
PrintF(&InterfaceString, "Unload %.*s", Assembly.Name.Length, Assembly.Name.Memory);
ButtonPos.x += ButtonDim.x + 10;
button_result UnloadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
InterfaceString, State->Interface, Mouse);
if (UnloadAssemblyBtn.Pressed)
{
UnloadAssembly(i, State, Context);
}
}
if (LoadAssemblyBtn.Pressed)
{
char FilePath[256];
b32 Success = Context.PlatformGetFilePath(FilePath, 256, "Foldhaus Files\0*.fold\0\0");
if (Success)
{
LoadAssembly(State, Context, FilePath);
}
}
}
DrawDebugInterface(RenderBuffer, 25,
State->Interface, Context.WindowWidth, Context.WindowHeight - TopBarHeight,
Context.DeltaTime, State, State->Camera, Mouse, &State->Transient);
#endif
}
DrawAllPanels(&State->PanelLayout, State->WindowBounds, RenderBuffer, State->Interface, Mouse, State, Context);
for (s32 m = 0; m < State->Modes.ActiveModesCount; m++) for (s32 m = 0; m < State->Modes.ActiveModesCount; m++)
{ {
@ -565,7 +501,6 @@ PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHe
} }
} }
// Checking for overflows // Checking for overflows
{ {
DEBUG_TRACK_SCOPE(OverflowChecks); DEBUG_TRACK_SCOPE(OverflowChecks);

View File

@ -13,15 +13,15 @@
#include "foldhaus_node.h" #include "foldhaus_node.h"
#include "assembly_parser.cpp" #include "assembly_parser.cpp"
#include "test_patterns.h" #include "test_patterns.h"
#include "foldhaus_interface.h"
typedef struct app_state app_state; typedef struct app_state app_state;
// TODO(Peter): something we can do later is to remove all reliance on app_state and context
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and
// perform operations on, like panel_draw_requests = { bounds, panel* } etc.
#include "foldhaus_panel.h" #include "foldhaus_panel.h"
#include "foldhaus_command_dispatch.h" #include "foldhaus_command_dispatch.h"
#include "foldhaus_command_dispatch.cpp"
#include "foldhaus_operation_mode.h" #include "foldhaus_operation_mode.h"
#include "animation/foldhaus_animation.h" #include "animation/foldhaus_animation.h"
@ -40,6 +40,8 @@ enum network_protocol
struct app_state struct app_state
{ {
rect WindowBounds;
memory_arena Permanent; memory_arena Permanent;
memory_arena Transient; memory_arena Transient;
@ -49,7 +51,6 @@ s32 NetworkProtocolHeaderSize;
streaming_acn SACN; streaming_acn SACN;
s32 TotalLEDsCount; s32 TotalLEDsCount;
assembly_array AssemblyList; assembly_array AssemblyList;
array_entry_handle_contiguous_array ActiveAssemblyIndecies; array_entry_handle_contiguous_array ActiveAssemblyIndecies;
@ -57,11 +58,9 @@ s32 NetworkProtocolHeaderSize;
r32 PixelsToWorldScale; r32 PixelsToWorldScale;
operation_mode_system Modes; operation_mode_system Modes;
input_command_registry DefaultInputCommandRegistry;
input_command_queue CommandQueue; input_command_queue CommandQueue;
text_entry ActiveTextEntry; text_entry ActiveTextEntry;
bitmap_font* Font;
interface_config Interface; interface_config Interface;
animation_system AnimationSystem; animation_system AnimationSystem;
@ -196,13 +195,10 @@ r32 GreenSize = 20.0f;
#include "foldhaus_assembly.cpp" #include "foldhaus_assembly.cpp"
#include "foldhaus_debug_visuals.h"
//#include "foldhaus_sacn_view.cpp"
#include "foldhaus_text_entry.cpp" #include "foldhaus_text_entry.cpp"
#include "foldhaus_search_lister.cpp" #include "foldhaus_search_lister.cpp"
#include "foldhaus_interface.cpp" #include "foldhaus_interface.cpp"
#include "animation/foldhaus_animation_interface.h"
#define PANEL_INIT_PROC(name) void name(panel* Panel) #define PANEL_INIT_PROC(name) void name(panel* Panel)
typedef PANEL_INIT_PROC(panel_init_proc); typedef PANEL_INIT_PROC(panel_init_proc);

View File

@ -1,149 +0,0 @@
internal void
InitializeInputCommandRegistry (input_command_registry* CommandRegistry,
s32 Size,
memory_arena* Storage)
{
CommandRegistry->Commands = PushArray(Storage, input_command, Size);
CommandRegistry->Size = Size;
CommandRegistry->Used = 0;
}
internal void
RegisterMouseWheelCommand (input_command_registry* CommandRegistry,
input_command_proc* Proc)
{
CommandRegistry->MouseWheelCommand = Proc;
}
internal s32
GetCommandIndexInQueue(input_command_queue* Queue, input_command Command, input_entry Event)
{
s32 Result = -1;
for (s32 CommandIndex = 0; CommandIndex < Queue->Used; CommandIndex++)
{
command_queue_entry* Entry = Queue->Commands + CommandIndex;
if(Entry->Event.Key == Event.Key)
{
Result = CommandIndex;
break;
}
}
return Result;
}
internal input_command_queue
InitializeCommandQueue(command_queue_entry* Memory, s32 MemorySize)
{
input_command_queue Result = {};
Result.Size = MemorySize;
Result.Used = 0;
Result.Commands = Memory;
return Result;
}
internal void
ClearCommandQueue(input_command_queue* Queue)
{
Queue->Used = 0;
}
internal void
PushCommandOnQueue(input_command_queue* Queue, input_command Command, input_entry Event)
{
Assert(Queue->Used < Queue->Size);
command_queue_entry Entry = {};
Entry.Command = Command;
Entry.Event = Event;
Queue->Commands[Queue->Used++] = Entry;
}
internal void
RemoveCommandFromQueue(input_command_queue* Queue, s32 Index)
{
s32 CommandIndex = Index;
if (CommandIndex < Queue->Used)
{
Queue->Used -= 1;
for (; CommandIndex < Queue->Used; CommandIndex++)
{
Queue->Commands[CommandIndex] = Queue->Commands[CommandIndex + 1];
}
}
}
internal void
RemoveCommandFromQueue(input_command_queue* Queue, input_command Command, input_entry Event)
{
s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event);
// NOTE(Peter): If we made it through the queue without finding an event, there wasn't one
// to remove. This happens when we've changed command registries as a result of an input command,
// and the command exists in the new registry.
// For example:
// clicking a mouse button triggers a command to switch registries
// the new registry tracks mouse drag (persist until release)
// when the mouse is released, the event fires, but there is no mouse down event to remove
// For this reason, I'm allowing the case where we try and remove a command where non exists
// I don't think this is a great solution but Im not super familiar with the codebase right now
// so leaving it as is. revisit if it becomes a problem.
RemoveCommandFromQueue(Queue, CommandIndex);
}
internal input_command*
FindExistingCommand (input_command_registry CommandRegistry, key_code Key, key_code Mdfr, b32 Flags)
{
input_command* Result = 0;
for (s32 Cmd = 0; Cmd < CommandRegistry.Used; Cmd++)
{
input_command* Command = CommandRegistry.Commands + Cmd;
if (Command->Key == Key && Command->Mdfr == Mdfr)
{
b32 FlagsOverlap = Flags & Command->Flags;
if (FlagsOverlap)
{
Result = Command;
break;
}
}
}
return Result;
}
internal b32
FindAndPushExistingCommand(input_command_registry CommandRegistry, input_entry Event, b32 Flags, input_command_queue* CommandQueue)
{
b32 CommandFound = false;
input_command* Command = FindExistingCommand(CommandRegistry, Event.Key, (key_code)0, Flags);
if (Command)
{
PushCommandOnQueue(CommandQueue, *Command, Event);
CommandFound = true;
}
return CommandFound;
}
internal void
RegisterKeyPressCommand (input_command_registry* CommandRegistry,
key_code Key,
b32 Flags,
key_code Mdfr,
input_command_proc* Proc)
{
input_command* Command = FindExistingCommand(*CommandRegistry, Key, Mdfr, Flags);
if (!Command)
{
Assert(CommandRegistry->Size > CommandRegistry->Used);
Assert(Mdfr == KeyCode_Invalid || Mdfr == KeyCode_LeftShift || Mdfr == KeyCode_RightShift ||
Mdfr == KeyCode_LeftCtrl || Mdfr == KeyCode_RightCtrl || Mdfr == KeyCode_Alt);
Command = CommandRegistry->Commands + CommandRegistry->Used++;
}
Command->Key = Key;
Command->Flags = Flags;
Command->Mdfr = Mdfr;
Command->Proc = Proc;
}

View File

@ -44,3 +44,153 @@ struct input_command_queue
s32 Used; s32 Used;
command_queue_entry* Commands; command_queue_entry* Commands;
}; };
internal void
InitializeInputCommandRegistry (input_command_registry* CommandRegistry,
s32 Size,
memory_arena* Storage)
{
CommandRegistry->Commands = PushArray(Storage, input_command, Size);
CommandRegistry->Size = Size;
CommandRegistry->Used = 0;
}
internal void
RegisterMouseWheelCommand (input_command_registry* CommandRegistry,
input_command_proc* Proc)
{
CommandRegistry->MouseWheelCommand = Proc;
}
internal s32
GetCommandIndexInQueue(input_command_queue* Queue, input_command Command, input_entry Event)
{
s32 Result = -1;
for (s32 CommandIndex = 0; CommandIndex < Queue->Used; CommandIndex++)
{
command_queue_entry* Entry = Queue->Commands + CommandIndex;
if(Entry->Event.Key == Event.Key)
{
Result = CommandIndex;
break;
}
}
return Result;
}
internal input_command_queue
InitializeCommandQueue(command_queue_entry* Memory, s32 MemorySize)
{
input_command_queue Result = {};
Result.Size = MemorySize;
Result.Used = 0;
Result.Commands = Memory;
return Result;
}
internal void
ClearCommandQueue(input_command_queue* Queue)
{
Queue->Used = 0;
}
internal void
PushCommandOnQueue(input_command_queue* Queue, input_command Command, input_entry Event)
{
Assert(Queue->Used < Queue->Size);
command_queue_entry Entry = {};
Entry.Command = Command;
Entry.Event = Event;
Queue->Commands[Queue->Used++] = Entry;
}
internal void
RemoveCommandFromQueue(input_command_queue* Queue, s32 Index)
{
s32 CommandIndex = Index;
if (CommandIndex < Queue->Used)
{
Queue->Used -= 1;
for (; CommandIndex < Queue->Used; CommandIndex++)
{
Queue->Commands[CommandIndex] = Queue->Commands[CommandIndex + 1];
}
}
}
internal void
RemoveCommandFromQueue(input_command_queue* Queue, input_command Command, input_entry Event)
{
s32 CommandIndex = GetCommandIndexInQueue(Queue, Command, Event);
// NOTE(Peter): If we made it through the queue without finding an event, there wasn't one
// to remove. This happens when we've changed command registries as a result of an input command,
// and the command exists in the new registry.
// For example:
// clicking a mouse button triggers a command to switch registries
// the new registry tracks mouse drag (persist until release)
// when the mouse is released, the event fires, but there is no mouse down event to remove
// For this reason, I'm allowing the case where we try and remove a command where non exists
// I don't think this is a great solution but Im not super familiar with the codebase right now
// so leaving it as is. revisit if it becomes a problem.
RemoveCommandFromQueue(Queue, CommandIndex);
}
internal input_command*
FindExistingCommand (input_command_registry CommandRegistry, key_code Key, key_code Mdfr, b32 Flags)
{
input_command* Result = 0;
for (s32 Cmd = 0; Cmd < CommandRegistry.Used; Cmd++)
{
input_command* Command = CommandRegistry.Commands + Cmd;
if (Command->Key == Key && Command->Mdfr == Mdfr)
{
b32 FlagsOverlap = Flags & Command->Flags;
if (FlagsOverlap)
{
Result = Command;
break;
}
}
}
return Result;
}
internal b32
FindAndPushExistingCommand(input_command_registry CommandRegistry, input_entry Event, b32 Flags, input_command_queue* CommandQueue)
{
b32 CommandFound = false;
input_command* Command = FindExistingCommand(CommandRegistry, Event.Key, (key_code)0, Flags);
if (Command)
{
PushCommandOnQueue(CommandQueue, *Command, Event);
CommandFound = true;
}
return CommandFound;
}
internal void
RegisterKeyPressCommand (input_command_registry* CommandRegistry,
key_code Key,
b32 Flags,
key_code Mdfr,
input_command_proc* Proc)
{
input_command* Command = FindExistingCommand(*CommandRegistry, Key, Mdfr, Flags);
if (!Command)
{
Assert(CommandRegistry->Size > CommandRegistry->Used);
Assert(Mdfr == KeyCode_Invalid || Mdfr == KeyCode_LeftShift || Mdfr == KeyCode_RightShift ||
Mdfr == KeyCode_LeftCtrl || Mdfr == KeyCode_RightCtrl || Mdfr == KeyCode_Alt);
Command = CommandRegistry->Commands + CommandRegistry->Used++;
}
Command->Key = Key;
Command->Flags = Flags;
Command->Mdfr = Mdfr;
Command->Proc = Proc;
}

View File

@ -1,195 +1,3 @@
#if 0
internal void
RenderProfiler_ScopeVisualization(render_command_buffer* RenderBuffer,
interface_config Interface, mouse_state Mouse,
v2 Min, v2 Max,
debug_frame* VisibleFrame, memory_arena* Memory)
{
v4 ThreadColors[] = {
v4{.73f, .33f, .83f, 1},
v4{0, .50f, .50f, 1},
v4{.83f, 0, 0, 1},
v4{.33f, .49f, .83f, 1},
v4{.74f, .40f, .25f, 1},
};
r32 Width = Max.x - Min.x;
r32 DepthHeight = 64;
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles;
debug_scope_record_list* ThreadScopeCalls = GetScopeListForThreadInFrame(GlobalDebugServices,
VisibleFrame);
MakeStringBuffer(String, 256);
for (s32 i = 0; i < ThreadScopeCalls->Count; i++)
{
scope_record* Record = ThreadScopeCalls->Calls + i;
scope_name* Name = GetOrAddNameHashEntry(VisibleFrame, Record->NameHash);
r32 PercentStart = (r32)(Record->StartCycles - FrameStartCycles) / (r32)FrameTotalCycles;
r32 PercentEnd = (r32)(Record->EndCycles - FrameStartCycles) / (r32)FrameTotalCycles;
v2 ScopeMin = v2{Min.x + (Width * PercentStart), Max.y - ((Record->CallDepth + 1) * DepthHeight)};
v2 ScopeMax = v2{Min.x + (Width * PercentEnd), ScopeMin.y + (DepthHeight - 4)};
if ((ScopeMax.x - ScopeMin.x) >= 1)
{
v4 Color = ThreadColors[0];
if (PointIsInRange(Mouse.Pos, ScopeMin, ScopeMax))
{
Color = GreenV4;
}
PushRenderQuad2D(RenderBuffer, ScopeMin, ScopeMax, Color);
PushRenderBoundingBox2D(RenderBuffer, ScopeMin, ScopeMax, 1, BlackV4);
if (PointIsInRange(Mouse.Pos, ScopeMin, ScopeMax))
{
PushRenderQuad2D(RenderBuffer, Mouse.Pos, Mouse.Pos + v2{256, 32}, BlackV4);
PrintF(&String, "%.*s : %d - %d", Name->Name.Length, Name->Name.Memory, Record->StartCycles, Record->EndCycles);
DrawString(RenderBuffer, String, Interface.Font, Mouse.Pos, WhiteV4);
}
}
}
}
internal void
RenderProfiler_ListVisualization(render_command_buffer* RenderBuffer,
interface_config Interface, mouse_state Mouse,
v2 Min, v2 Max,
debug_frame* VisibleFrame, memory_arena* Memory)
{
MakeStringBuffer(String, 256);
r32 YAt = Max.y - Interface.Font->PixelHeight;
r32 Column0X = Min.x;
r32 Column1X = Column0X + 256;
r32 Column2X = Column1X + 128;
r32 Column3X = Column2X + 128;
r32 Column4X = Column3X + 100;
for (s32 n = 0; n < VisibleFrame->ScopeNamesMax; n++)
{
scope_name NameEntry = VisibleFrame->ScopeNamesHash[n];
if (NameEntry.Hash != 0)
{
collated_scope_record* CollatedRecord = VisibleFrame->CollatedScopes + n;
PrintF(&String, "%.*s", NameEntry.Name.Length, NameEntry.Name.Memory);
DrawString(RenderBuffer, String, Interface.Font, v2{Column0X, YAt}, WhiteV4);
PrintF(&String, "%f", CollatedRecord->PercentFrameTime);
DrawString(RenderBuffer, String, Interface.Font, v2{Column1X, YAt}, WhiteV4);
PrintF(&String, "%fs", CollatedRecord->TotalSeconds);
DrawString(RenderBuffer, String, Interface.Font, v2{Column2X, YAt}, WhiteV4);
PrintF(&String, "%dcy", CollatedRecord->TotalCycles);
DrawString(RenderBuffer, String, Interface.Font, v2{Column3X, YAt}, WhiteV4);
PrintF(&String, "%d calls", CollatedRecord->CallCount);
DrawString(RenderBuffer, String, Interface.Font, v2{Column4X, YAt}, WhiteV4);
YAt -= Interface.Font->PixelHeight + 4;
if (YAt < Min.y) { break; }
}
}
}
internal void
DrawDebugFrameList (render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, v2 BoundsMin, v2 BoundsMax, memory_arena* Memory)
{
string String = InitializeEmptyString(PushArray(Memory, char, 256), 256);
v4 FrameColors[] = { GreenV4, YellowV4, RedV4, WhiteV4 };
r32 FrameListHeight = 64;
v2 FrameListMin = v2{BoundsMin.x + 16, BoundsMax.y - (16 + FrameListHeight)};
v2 FrameListMax = v2{BoundsMax.x - 16, BoundsMax.y - 16};
r32 FrameListPadding = 4;
r32 FrameListInnerWidth = (FrameListMax.x - FrameListMin.x) - (FrameListPadding * 2);
r32 SingleFrameStep = FrameListInnerWidth / DEBUG_FRAME_COUNT;
r32 SingleFrameWidth = (r32)((s32)SingleFrameStep - 2);
PushRenderBoundingBox2D(RenderBuffer, FrameListMin, FrameListMax, 2, WhiteV4);
if (PointIsInRange(Mouse.Pos, FrameListMin, FrameListMax) &&
MouseButtonHeldDown(Mouse.LeftButtonState))
{
r32 LocalMouseX = (Mouse.Pos.x - FrameListMin.x) + FrameListPadding;
s32 ClosestFrameIndex = (LocalMouseX / SingleFrameStep);
if (ClosestFrameIndex >= 0 && ClosestFrameIndex < DEBUG_FRAME_COUNT)
{
GlobalDebugServices->RecordFrames = false;
GlobalDebugServices->CurrentDebugFrame = ClosestFrameIndex;
}
}
for (s32 F = 0; F < DEBUG_FRAME_COUNT; F++)
{
v2 Min = v2{FrameListMin.x + FrameListPadding + (F * SingleFrameStep), FrameListMin.y + 4};
v2 Max = v2{Min.x + SingleFrameWidth, FrameListMax.y - 4};
s32 FramesAgo = (GlobalDebugServices->CurrentDebugFrame - F);
if (FramesAgo < 0) { FramesAgo += DEBUG_FRAME_COUNT; }
v4 Color = FrameColors[GSClamp(0, FramesAgo, 3)];
PushRenderQuad2D(RenderBuffer, Min, Max, Color);
}
debug_frame* VisibleFrame = GetLastDebugFrame(GlobalDebugServices);
s64 FrameStartCycles = VisibleFrame->FrameStartCycles;
s64 FrameTotalCycles = VisibleFrame->FrameEndCycles - VisibleFrame->FrameStartCycles;
PrintF(&String, "Frame %d - Total Cycles: %lld",
GlobalDebugServices->CurrentDebugFrame - 1,
FrameTotalCycles);
DrawString(RenderBuffer, String, Interface.Font, FrameListMin - v2{0, 32}, WhiteV4);
v2 ButtonMin = v2{FrameListMax.x - 128, FrameListMin.y - 32};
v2 ButtonMax = ButtonMin + v2{128, 28};
button_result ShouldResumeRecording = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
MakeString("Resume Recording"), Interface, Mouse);
if (ShouldResumeRecording.Pressed)
{
GlobalDebugServices->RecordFrames = true;
}
ButtonMin = v2{FrameListMin.x, FrameListMin.y - 60};
ButtonMax = v2{FrameListMin.x + 128, FrameListMin.y - 42};
button_result ActivateScopeView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
MakeString("Scope View"), Interface, Mouse);
ButtonMin.x += 152;
ButtonMax.x += 152;
button_result ActivateListView = EvaluateButton(RenderBuffer, ButtonMin, ButtonMax,
MakeString("List View"), Interface, Mouse);
if (ActivateScopeView.Pressed) { GlobalDebugServices->Interface.FrameView = FRAME_VIEW_PROFILER; }
if (ActivateListView.Pressed) { GlobalDebugServices->Interface.FrameView = FRAME_VIEW_SCOPE_LIST; }
v2 ViewModeMin = v2{FrameListMin.x, BoundsMin.y};
v2 ViewModeMax = v2{FrameListMax.x, FrameListMin.y - 96};
if (GlobalDebugServices->Interface.FrameView == FRAME_VIEW_PROFILER)
{
RenderProfiler_ScopeVisualization(RenderBuffer, Interface, Mouse,
ViewModeMin, ViewModeMax,
VisibleFrame, Memory);
}
else
{
RenderProfiler_ListVisualization(RenderBuffer, Interface, Mouse,
ViewModeMin, ViewModeMax,
VisibleFrame, Memory);
}
}
#endif
internal void internal void
DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_config Interface, r32 WindowWidth, r32 WindowHeight, r32 DeltaTime, app_state* State, camera Camera, mouse_state Mouse, memory_arena* Transient) DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_config Interface, r32 WindowWidth, r32 WindowHeight, r32 DeltaTime, app_state* State, camera Camera, mouse_state Mouse, memory_arena* Transient)
{ {
@ -198,8 +6,6 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
v2 TopOfDebugView = v2{StartX, WindowHeight - (NewLineYOffset(*Interface.Font) + 5)}; v2 TopOfDebugView = v2{StartX, WindowHeight - (NewLineYOffset(*Interface.Font) + 5)};
v2 TopOfScreenLinePos = TopOfDebugView; v2 TopOfScreenLinePos = TopOfDebugView;
//arena_snapshot StartTempMemory = TakeSnapshotOfArena(*Transient);
string DebugString = InitializeEmptyString(PushArray(Transient, char, 256), 256); string DebugString = InitializeEmptyString(PushArray(Transient, char, 256), 256);
if (GlobalDebugServices->Interface.ShowCameraMouse) if (GlobalDebugServices->Interface.ShowCameraMouse)
@ -306,55 +112,4 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
TopOfScreenLinePos, WhiteV4); TopOfScreenLinePos, WhiteV4);
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font); TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
} }
if (GlobalDebugServices->Interface.ShowTrackedScopes)
{
v2 ProfilerMin = v2{TopOfDebugView.x, TopOfDebugView.y - 500};
v2 ProfilerMax = v2{TopOfDebugView.x + 700, TopOfDebugView.y - 64};
PushRenderQuad2D(RenderBuffer, ProfilerMin, ProfilerMax, v4{0, 0, 0, .8f});
//DrawDebugFrameList(RenderBuffer, Interface, Mouse, ProfilerMin, ProfilerMax, Transient);
#if 0
r32 ColumnsStartX = TopOfScreenLinePos.x;
for (s32 i = 0; i < GlobalDebugServices->ScopeHistogramUsed; i++)
{
v2 Register = v2{ColumnsStartX, TopOfScreenLinePos.y};
s32 CurrentFrame = GlobalDebugServices->ScopeHistogramSorted[i].CurrentFrame - 1;
if (CurrentFrame < 0) { CurrentFrame = HISTOGRAM_DEPTH - 1; }
u64 CyclesPerHit = GlobalDebugServices->ScopeHistogramSorted[i].PerFrame_Cycles[CurrentFrame];
r32 SecondsPerHit = (r32)CyclesPerHit / (r32)GlobalDebugServices->PerformanceCountFrequency;
// Column 1
PrintF(&DebugString, "%.*s",
GlobalDebugServices->ScopeHistogramSorted[i].ScopeName.Length,
GlobalDebugServices->ScopeHistogramSorted[i].ScopeName.Memory);
r32 ColumnOneX = DrawString(RenderBuffer, DebugString, Interface.Font,
Register, WhiteV4).x;
Register.x += GSMax(ColumnOneX - Register.x, 250.f);
// Column 2
PrintF(&DebugString, "%d hits", GlobalDebugServices->ScopeHistogramSorted[i].PerFrame_CallCount[CurrentFrame]);
r32 ColumnTwoX = DrawString(RenderBuffer, DebugString, Interface.Font,
Register, WhiteV4).x;
Register.x += GSMax(ColumnTwoX - Register.x, 150.f);
// Column 3
PrintF(&DebugString, "%lld cycles", CyclesPerHit);
r32 ColumnThreeX = DrawString(RenderBuffer, DebugString, Interface.Font,
Register, WhiteV4).x;
Register.x += GSMax(ColumnThreeX - Register.x, 200.f);
PrintF(&DebugString, "%f sec", SecondsPerHit);
r32 ColumnFourX = DrawString(RenderBuffer, DebugString, Interface.Font,
Register, WhiteV4).x;
Register.x += GSMax(ColumnFourX - Register.x, 200.f);
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
}
#endif
}
} }

View File

@ -127,47 +127,3 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenUniverseView)
OpState->DisplayOffset = v2{0, 0}; OpState->DisplayOffset = v2{0, 0};
OpState->Zoom = 1.0f; OpState->Zoom = 1.0f;
} }
////////////////////////////////////////
//
// 3D View Mouse Rotate
//
///////////////////////////////////////
struct mouse_rotate_view_operation_state
{
v4 CameraStartPos;
};
OPERATION_RENDER_PROC(Update3DViewMouseRotate)
{
mouse_rotate_view_operation_state* OpState = (mouse_rotate_view_operation_state*)Operation.OpStateMemory;
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
m44 XRotation = GetXRotation(-TotalDeltaPos.y * State->PixelsToWorldScale);
m44 YRotation = GetYRotation(TotalDeltaPos.x * State->PixelsToWorldScale);
m44 Combined = XRotation * YRotation;
State->Camera.Position = V3(Combined * OpState->CameraStartPos);
}
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
{
DeactivateCurrentOperationMode(&State->Modes);
}
input_command MouseRotateViewCommands [] = {
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, End3DViewMouseRotate},
};
FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate)
{
operation_mode* RotateViewMode = ActivateOperationModeWithCommands(&State->Modes, MouseRotateViewCommands);
RotateViewMode->Render = Update3DViewMouseRotate;
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
&State->Modes,
mouse_rotate_view_operation_state);
OpState->CameraStartPos = V4(State->Camera.Position, 1);
}

View File

@ -129,10 +129,10 @@ FreePanelAtIndex(s32 Index, panel_layout* Layout)
} }
internal void internal void
SplitPanelVertically(panel* Parent, r32 Percent, v2 ParentMin, v2 ParentMax, panel_layout* Layout) SplitPanelVertically(panel* Parent, r32 Percent, rect ParentBounds, panel_layout* Layout)
{ {
r32 SplitX = GSLerp(ParentMin.x, ParentMax.x, Percent); r32 SplitX = GSLerp(ParentBounds.Min.x, ParentBounds.Max.x, Percent);
if (SplitX > ParentMin.x && SplitX < ParentMax.x) if (SplitX > ParentBounds.Min.x && SplitX < ParentBounds.Max.x)
{ {
Parent->SplitDirection = PanelSplit_Vertical; Parent->SplitDirection = PanelSplit_Vertical;
Parent->SplitPercent = Percent; Parent->SplitPercent = Percent;
@ -146,10 +146,10 @@ Parent->Right = TakeNewPanelEntry(Layout);
} }
internal void internal void
SplitPanelHorizontally(panel* Parent, r32 Percent, v2 ParentMin, v2 ParentMax, panel_layout* Layout) SplitPanelHorizontally(panel* Parent, r32 Percent, rect ParentBounds, panel_layout* Layout)
{ {
r32 SplitY = GSLerp(ParentMin.y, ParentMax.y, Percent); r32 SplitY = GSLerp(ParentBounds.Min.y, ParentBounds.Max.y, Percent);
if (SplitY > ParentMin.y && SplitY < ParentMax.y) if (SplitY > ParentBounds.Min.y && SplitY < ParentBounds.Max.y)
{ {
Parent->SplitDirection = PanelSplit_Horizontal; Parent->SplitDirection = PanelSplit_Horizontal;
Parent->SplitPercent = Percent; Parent->SplitPercent = Percent;
@ -182,91 +182,203 @@ SetPanelDefinition(panel* Panel, s32 NewDefinitionIndex)
Panel->PanelDefinitionIndex = NewDefinitionIndex; Panel->PanelDefinitionIndex = NewDefinitionIndex;
SetPanelDefinitionExternal(Panel, OldDefinitionIndex, NewDefinitionIndex); SetPanelDefinitionExternal(Panel, OldDefinitionIndex, NewDefinitionIndex);
} }
///////////////////////////////// /////////////////////////////////
// //
// Rendering And Interaction // Rendering And Interaction
// //
///////////////////////////////// /////////////////////////////////
internal rect
GetTopPanelBounds(panel* Panel, rect PanelBounds)
{
rect Result = {};
Result.Min = v2{
PanelBounds.Min.x,
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent)
};
Result.Max = PanelBounds.Max;
return Result;
}
internal rect
GetBottomPanelBounds(panel* Panel, rect PanelBounds)
{
rect Result = {};
Result.Min = PanelBounds.Min;
Result.Max = v2{
PanelBounds.Max.x,
GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent)
};
return Result;
}
internal rect
GetRightPanelBounds(panel* Panel, rect PanelBounds)
{
rect Result = {};
Result.Min = v2{
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent),
PanelBounds.Min.y
};
Result.Max = PanelBounds.Max;
return Result;
}
internal rect
GetLeftPanelBounds(panel* Panel, rect PanelBounds)
{
rect Result = {};
Result.Min = PanelBounds.Min;
Result.Max = v2{
GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent),
PanelBounds.Max.y
};
return Result;
}
struct panel_and_bounds
{
panel* Panel;
rect Bounds;
};
internal panel_and_bounds
GetPanelContainingPoint(v2 Point, panel* Panel, rect PanelBounds)
{
panel_and_bounds Result = {0};
if (Panel->SplitDirection == PanelSplit_NoSplit)
{
Result.Panel = Panel;
Result.Bounds = PanelBounds;
}
else if (Panel->SplitDirection == PanelSplit_Horizontal)
{
rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
if (PointIsInRange(Point, TopPanelBounds.Min, TopPanelBounds.Max))
{
Result = GetPanelContainingPoint(Point, &Panel->Top->Panel, TopPanelBounds);
}
else if (PointIsInRange(Point, BottomPanelBounds.Min, BottomPanelBounds.Max))
{
Result = GetPanelContainingPoint(Point, &Panel->Bottom->Panel, BottomPanelBounds);
}
}
else if (Panel->SplitDirection == PanelSplit_Vertical)
{
rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
if (PointIsInRange(Point, LeftPanelBounds.Min, LeftPanelBounds.Max))
{
Result = GetPanelContainingPoint(Point, &Panel->Left->Panel, LeftPanelBounds);
}
else if (PointIsInRange(Point, RightPanelBounds.Min, RightPanelBounds.Max))
{
Result = GetPanelContainingPoint(Point, &Panel->Right->Panel, RightPanelBounds);
}
}
return Result;
}
internal panel_and_bounds
GetPanelContainingPoint(v2 Point, panel_layout* Layout, rect WindowBounds)
{
panel_and_bounds Result = {0};
if (Layout->PanelsUsed > 0)
{
Result = GetPanelContainingPoint(Point, &Layout->Panels[0].Panel, WindowBounds);
}
return Result;
}
internal void internal void
HandleMousePanelInteractionOrRecurse(panel* Panel, v2 PanelMin, v2 PanelMax, panel_layout* PanelLayout, mouse_state Mouse) HandleMousePanelInteractionOrRecurse(panel* Panel, rect PanelBounds, panel_layout* PanelLayout, mouse_state Mouse)
{ {
r32 PanelEdgeClickMaxDistance = 4; r32 PanelEdgeClickMaxDistance = 4;
// TODO(Peter): Need a way to calculate this button's position more systemically // TODO(Peter): Need a way to calculate this button's position more systemically
if (Panel->SplitDirection == PanelSplit_NoSplit if (Panel->SplitDirection == PanelSplit_NoSplit
&& PointIsInRange(Mouse.DownPos, PanelMin, PanelMin + v2{25, 25})) && PointIsInRange(Mouse.DownPos, PanelBounds.Min, PanelBounds.Min + v2{25, 25}))
{ {
r32 XDistance = GSAbs(Mouse.Pos.x - Mouse.DownPos.x); r32 XDistance = GSAbs(Mouse.Pos.x - Mouse.DownPos.x);
r32 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y); r32 YDistance = GSAbs(Mouse.Pos.y - Mouse.DownPos.y);
if (XDistance > YDistance) if (XDistance > YDistance)
{ {
r32 XPercent = (Mouse.Pos.x - PanelMin.x) / (PanelMax.x - PanelMin.x); r32 XPercent = (Mouse.Pos.x - PanelBounds.Min.x) / Width(PanelBounds);
SplitPanelVertically(Panel, XPercent, PanelMin, PanelMax, PanelLayout); SplitPanelVertically(Panel, XPercent, PanelBounds, PanelLayout);
} }
else else
{ {
r32 YPercent = (Mouse.Pos.y - PanelMin.y) / (PanelMax.y - PanelMin.y); r32 YPercent = (Mouse.Pos.y - PanelBounds.Min.y) / Height(PanelBounds);
SplitPanelHorizontally(Panel, YPercent, PanelMin, PanelMax, PanelLayout); SplitPanelHorizontally(Panel, YPercent, PanelBounds, PanelLayout);
} }
} }
else if (Panel->SplitDirection == PanelSplit_Horizontal) else if (Panel->SplitDirection == PanelSplit_Horizontal)
{ {
r32 SplitY = GSLerp(PanelMin.y, PanelMax.y, Panel->SplitPercent); r32 SplitY = GSLerp(PanelBounds.Min.y, PanelBounds.Max.y, Panel->SplitPercent);
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.y - SplitY); r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.y - SplitY);
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance) if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
{ {
r32 NewSplitY = Mouse.Pos.y; r32 NewSplitY = Mouse.Pos.y;
if (NewSplitY <= PanelMin.y) if (NewSplitY <= PanelBounds.Min.y)
{ {
ConsolidatePanelsKeepOne(Panel, Panel->Top, PanelLayout); ConsolidatePanelsKeepOne(Panel, Panel->Top, PanelLayout);
} }
else if (NewSplitY >= PanelMax.y) else if (NewSplitY >= PanelBounds.Max.y)
{ {
ConsolidatePanelsKeepOne(Panel, Panel->Bottom, PanelLayout); ConsolidatePanelsKeepOne(Panel, Panel->Bottom, PanelLayout);
} }
else else
{ {
Panel->SplitPercent = (NewSplitY - PanelMin.y) / (PanelMax.y - PanelMin.y); Panel->SplitPercent = (NewSplitY - PanelBounds.Min.y) / Height(PanelBounds);
} }
} }
else else
{ {
HandleMousePanelInteractionOrRecurse(&Panel->Bottom->Panel, PanelMin, v2{PanelMax.x, SplitY}, PanelLayout, Mouse); rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
HandleMousePanelInteractionOrRecurse(&Panel->Top->Panel, v2{PanelMin.x, SplitY}, PanelMax, PanelLayout, Mouse); rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
HandleMousePanelInteractionOrRecurse(&Panel->Bottom->Panel, BottomPanelBounds, PanelLayout, Mouse);
HandleMousePanelInteractionOrRecurse(&Panel->Top->Panel, TopPanelBounds, PanelLayout, Mouse);
} }
} }
else if (Panel->SplitDirection == PanelSplit_Vertical) else if (Panel->SplitDirection == PanelSplit_Vertical)
{ {
r32 SplitX = GSLerp(PanelMin.x, PanelMax.x, Panel->SplitPercent); r32 SplitX = GSLerp(PanelBounds.Min.x, PanelBounds.Max.x, Panel->SplitPercent);
r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.x - SplitX); r32 ClickDistanceFromSplit = GSAbs(Mouse.DownPos.x - SplitX);
if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance) if (ClickDistanceFromSplit < PanelEdgeClickMaxDistance)
{ {
r32 NewSplitX = Mouse.Pos.x; r32 NewSplitX = Mouse.Pos.x;
if (NewSplitX <= PanelMin.x) if (NewSplitX <= PanelBounds.Min.x)
{ {
ConsolidatePanelsKeepOne(Panel, Panel->Right, PanelLayout); ConsolidatePanelsKeepOne(Panel, Panel->Right, PanelLayout);
} }
else if (NewSplitX >= PanelMax.x) else if (NewSplitX >= PanelBounds.Max.x)
{ {
ConsolidatePanelsKeepOne(Panel, Panel->Left, PanelLayout); ConsolidatePanelsKeepOne(Panel, Panel->Left, PanelLayout);
} }
else else
{ {
Panel->SplitPercent = (NewSplitX - PanelMin.x) / (PanelMax.x - PanelMin.x); Panel->SplitPercent = (NewSplitX - PanelBounds.Min.x) / Width(PanelBounds);
} }
} }
else else
{ {
HandleMousePanelInteractionOrRecurse(&Panel->Left->Panel, PanelMin, v2{SplitX, PanelMax.y}, PanelLayout, Mouse); rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
HandleMousePanelInteractionOrRecurse(&Panel->Right->Panel, v2{SplitX, PanelMin.y}, PanelMax, PanelLayout, Mouse); rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
HandleMousePanelInteractionOrRecurse(&Panel->Left->Panel, LeftPanelBounds, PanelLayout, Mouse);
HandleMousePanelInteractionOrRecurse(&Panel->Right->Panel, RightPanelBounds, PanelLayout, Mouse);
} }
} }
} }
internal void internal void
HandleMousePanelInteraction(panel_layout* PanelLayout, v2 WindowMin, v2 WindowMax, mouse_state Mouse) HandleMousePanelInteraction(panel_layout* PanelLayout, rect WindowBounds, mouse_state Mouse)
{ {
r32 PanelEdgeClickMaxDistance = 4; r32 PanelEdgeClickMaxDistance = 4;
@ -274,7 +386,7 @@ HandleMousePanelInteraction(panel_layout* PanelLayout, v2 WindowMin, v2 WindowMa
{ {
Assert(PanelLayout->PanelsUsed > 0); Assert(PanelLayout->PanelsUsed > 0);
panel* FirstPanel = &PanelLayout->Panels[0].Panel; panel* FirstPanel = &PanelLayout->Panels[0].Panel;
HandleMousePanelInteractionOrRecurse(FirstPanel, WindowMin, WindowMax, PanelLayout, Mouse); HandleMousePanelInteractionOrRecurse(FirstPanel, WindowBounds, PanelLayout, Mouse);
} }
} }
@ -285,11 +397,11 @@ DrawPanelBorder(panel Panel, v2 PanelMin, v2 PanelMax, v4 Color, render_command_
} }
internal void internal void
DrawPanelOrRecurse(panel* Panel, v2 PanelMin, v2 PanelMax, v2 WindowMin, v2 WindowMax, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context) DrawPanelOrRecurse(panel* Panel, rect PanelBounds, rect WindowRect, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context)
{ {
if (Panel->SplitDirection == PanelSplit_NoSplit) if (Panel->SplitDirection == PanelSplit_NoSplit)
{ {
RenderPanel(Panel, PanelMin, PanelMax, WindowMin, WindowMax, RenderBuffer, State, Context, Mouse); RenderPanel(Panel, PanelBounds.Min, PanelBounds.Max, WindowRect.Min, WindowRect.Max, RenderBuffer, State, Context, Mouse);
v4 BorderColor = v4{0, 0, 0, 1}; v4 BorderColor = v4{0, 0, 0, 1};
#if 0 #if 0
@ -299,27 +411,31 @@ DrawPanelOrRecurse(panel* Panel, v2 PanelMin, v2 PanelMax, v2 WindowMin, v2 Wind
} }
#endif #endif
PushRenderOrthographic(RenderBuffer, WindowMin.x, WindowMin.y, WindowMax.x, WindowMax.y); PushRenderOrthographic(RenderBuffer, WindowRect.Min.x, WindowRect.Min.y, WindowRect.Max.x, WindowRect.Max.y);
DrawPanelBorder(*Panel, PanelMin, PanelMax, BorderColor, RenderBuffer); DrawPanelBorder(*Panel, PanelBounds.Min, PanelBounds.Max, BorderColor, RenderBuffer);
} }
else if (Panel->SplitDirection == PanelSplit_Horizontal) else if (Panel->SplitDirection == PanelSplit_Horizontal)
{ {
r32 SplitY = GSLerp(PanelMin.y, PanelMax.y, Panel->SplitPercent); rect TopPanelBounds = GetTopPanelBounds(Panel, PanelBounds);
DrawPanelOrRecurse(&Panel->Bottom->Panel, PanelMin, v2{PanelMax.x, SplitY}, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context); rect BottomPanelBounds = GetBottomPanelBounds(Panel, PanelBounds);
DrawPanelOrRecurse(&Panel->Top->Panel, v2{PanelMin.x, SplitY}, PanelMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
DrawPanelOrRecurse(&Panel->Bottom->Panel, BottomPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
DrawPanelOrRecurse(&Panel->Top->Panel, TopPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
} }
else if (Panel->SplitDirection == PanelSplit_Vertical) else if (Panel->SplitDirection == PanelSplit_Vertical)
{ {
r32 SplitX = GSLerp(PanelMin.x, PanelMax.x, Panel->SplitPercent); rect LeftPanelBounds = GetLeftPanelBounds(Panel, PanelBounds);
DrawPanelOrRecurse(&Panel->Left->Panel, PanelMin, v2{SplitX, PanelMax.y}, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context); rect RightPanelBounds = GetRightPanelBounds(Panel, PanelBounds);
DrawPanelOrRecurse(&Panel->Right->Panel, v2{SplitX, PanelMin.y}, PanelMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context);
DrawPanelOrRecurse(&Panel->Left->Panel, LeftPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
DrawPanelOrRecurse(&Panel->Right->Panel, RightPanelBounds, WindowRect, RenderBuffer, Interface, Mouse, State, Context);
} }
} }
internal void internal void
DrawAllPanels(panel_layout PanelLayout, v2 WindowMin, v2 WindowMax, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context) DrawAllPanels(panel_layout* PanelLayout, rect WindowBounds, render_command_buffer* RenderBuffer, interface_config Interface, mouse_state Mouse, app_state* State, context Context)
{ {
Assert(PanelLayout.PanelsUsed > 0); Assert(PanelLayout->PanelsUsed > 0);
panel* FirstPanel = &PanelLayout.Panels[0].Panel; panel* FirstPanel = &PanelLayout->Panels[0].Panel;
DrawPanelOrRecurse(FirstPanel, WindowMin, WindowMax, WindowMin, WindowMax, RenderBuffer, Interface, Mouse, State, Context); DrawPanelOrRecurse(FirstPanel, WindowBounds, WindowBounds, RenderBuffer, Interface, Mouse, State, Context);
} }

View File

@ -122,8 +122,7 @@ struct context
u32 MemorySize; u32 MemorySize;
b32 WindowIsVisible; b32 WindowIsVisible;
r32 WindowWidth; rect WindowBounds;
r32 WindowHeight;
r32 DeltaTime; r32 DeltaTime;
// Application Services // Application Services

View File

@ -11,7 +11,7 @@ struct panel_definition
global_variable s32 GlobalPanelDefsCount = 5; global_variable s32 GlobalPanelDefsCount = 5;
global_variable panel_definition GlobalPanelDefs[] = { global_variable panel_definition GlobalPanelDefs[] = {
{ "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands}, { "Sculpture View", 14, SculptureView_Init, SculptureView_Cleanup, SculptureView_Render, SculptureView_Commands},
{ "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, 0 }, { "Animation Timeline", 18, AnimationTimeline_Init, AnimationTimeline_Cleanup, AnimationTimeline_Render, AnimationTimeline_Commands },
{ "DMX View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, 0 }, { "DMX View", 8, DMXView_Init, DMXView_Cleanup, DMXView_Render, 0 },
{ "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, 0 }, { "Profiler", 8, ProfilerView_Init, ProfilerView_Cleanup, ProfilerView_Render, 0 },
{ "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, 0 }, { "Hierarchy", 9, HierarchyView_Init, HierarchyView_Cleanup, HierarchyView_Render, 0 },

View File

@ -7,6 +7,62 @@
// [] - displaying multiple layers // [] - displaying multiple layers
// [] - // [] -
internal void
DeleteAnimationBlock(animation_block_handle AnimationBlockHandle, app_state* State)
{
RemoveAnimationBlock(State->SelectedAnimationBlockHandle, &State->AnimationSystem);
State->SelectedAnimationBlockHandle = {0};
}
internal void
SelectAnimationBlock(animation_block_handle BlockHandle, app_state* State)
{
State->SelectedAnimationBlockHandle = BlockHandle;
}
internal void
SelectAndBeginDragAnimationBlock(animation_block_handle BlockHandle, app_state* State)
{
SelectAnimationBlock(BlockHandle, State);
// TODO(Peter): Begin Dragging Mode
}
internal void
DeselectCurrentAnimationBlock(app_state* State)
{
State->SelectedAnimationBlockHandle = {};
}
FOLDHAUS_INPUT_COMMAND_PROC(DeleteAnimationBlockCommand)
{
if (AnimationBlockHandleIsValid(State->SelectedAnimationBlockHandle))
{
DeleteAnimationBlock(State->SelectedAnimationBlockHandle, State);
}
}
FOLDHAUS_INPUT_COMMAND_PROC(AddAnimationBlockCommand)
{
panel_and_bounds ActivePanel = GetPanelContainingPoint(Mouse.Pos, &State->PanelLayout, State->WindowBounds);
r32 MouseDownPositionPercent = (Mouse.Pos.x - ActivePanel.Bounds.Min.x) / Width(ActivePanel.Bounds);
r32 NewBlockTimeStart = MouseDownPositionPercent * State->AnimationSystem.AnimationEnd;
#define NEW_BLOCK_DURATION 1
r32 NewBlockTimeEnd = NewBlockTimeStart + NEW_BLOCK_DURATION;
animation_block Block = {0};
Block.StartTime = NewBlockTimeStart;
Block.EndTime = NewBlockTimeEnd;
Block.Proc = TestPatternThree;
animation_block_handle NewBlockHandle = AddAnimationBlock(Block, &State->AnimationSystem);
SelectAnimationBlock(NewBlockHandle, State);
}
input_command AnimationTimeline_Commands[] = {
{ KeyCode_X, KeyCode_Invalid, Command_Began, DeleteAnimationBlockCommand },
{ KeyCode_A, KeyCode_Invalid, Command_Began, AddAnimationBlockCommand },
};
PANEL_INIT_PROC(AnimationTimeline_Init) PANEL_INIT_PROC(AnimationTimeline_Init)
{ {
@ -139,15 +195,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 En
&& MouseButtonTransitionedDown(Mouse.LeftButtonState)) && MouseButtonTransitionedDown(Mouse.LeftButtonState))
{ {
MouseDownAndNotHandled = false; MouseDownAndNotHandled = false;
if (AnimationBlockHandlesAreEqual(SelectedBlockHandle, CurrentBlockHandle)) SelectAndBeginDragAnimationBlock(CurrentBlockHandle, State);
{
// If the block is already selected, deselect it.
Result = {0};
}
else
{
Result = CurrentBlockHandle;
}
} }
} }
@ -171,18 +219,7 @@ DrawAnimationTimeline (animation_system* AnimationSystem, s32 StartFrame, s32 En
if (MouseDownAndNotHandled && PointIsInRange(Mouse.Pos, TimelineMin, TimelineMax)) if (MouseDownAndNotHandled && PointIsInRange(Mouse.Pos, TimelineMin, TimelineMax))
{ {
r32 MouseDownPositionPercent = (Mouse.Pos.x - PanelMin.x) / AnimationPanelWidth; DeselectCurrentAnimationBlock(State);
r32 NewBlockTimeStart = MouseDownPositionPercent * AnimationSystem->AnimationEnd;
#define NEW_BLOCK_DURATION 1
r32 NewBlockTimeEnd = NewBlockTimeStart + NEW_BLOCK_DURATION;
animation_block Block = {0};
Block.StartTime = NewBlockTimeStart;
Block.EndTime = NewBlockTimeEnd;
Block.Proc = TestPatternThree;
animation_block_handle NewBlockHandle = AddAnimationBlock(Block, AnimationSystem);
Result = NewBlockHandle;
} }
return Result; return Result;
} }
@ -245,6 +282,4 @@ PANEL_RENDER_PROC(AnimationTimeline_Render)
State->AnimationSystem.TimelineShouldAdvance = false; State->AnimationSystem.TimelineShouldAdvance = false;
State->AnimationSystem.Time = 0; State->AnimationSystem.Time = 0;
} }
State->SelectedAnimationBlockHandle = SelectedBlockHandle;
} }

View File

@ -1,3 +1,46 @@
// 3D Mouse View
struct mouse_rotate_view_operation_state
{
v4 CameraStartPos;
};
OPERATION_RENDER_PROC(Update3DViewMouseRotate)
{
mouse_rotate_view_operation_state* OpState = (mouse_rotate_view_operation_state*)Operation.OpStateMemory;
v2 TotalDeltaPos = Mouse.Pos - Mouse.DownPos;
m44 XRotation = GetXRotation(-TotalDeltaPos.y * State->PixelsToWorldScale);
m44 YRotation = GetYRotation(TotalDeltaPos.x * State->PixelsToWorldScale);
m44 Combined = XRotation * YRotation;
State->Camera.Position = V3(Combined * OpState->CameraStartPos);
}
FOLDHAUS_INPUT_COMMAND_PROC(End3DViewMouseRotate)
{
DeactivateCurrentOperationMode(&State->Modes);
}
input_command MouseRotateViewCommands [] = {
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, End3DViewMouseRotate},
};
FOLDHAUS_INPUT_COMMAND_PROC(Begin3DViewMouseRotate)
{
operation_mode* RotateViewMode = ActivateOperationModeWithCommands(&State->Modes, MouseRotateViewCommands);
RotateViewMode->Render = Update3DViewMouseRotate;
mouse_rotate_view_operation_state* OpState = CreateOperationState(RotateViewMode,
&State->Modes,
mouse_rotate_view_operation_state);
OpState->CameraStartPos = V4(State->Camera.Position, 1);
}
// ----------------
input_command SculptureView_Commands[] = { input_command SculptureView_Commands[] = {
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate }, { KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, Begin3DViewMouseRotate },
}; };

View File

@ -560,8 +560,7 @@ INT NCmdShow
context Context = {}; context Context = {};
Context.MemorySize = InitialMemorySize; Context.MemorySize = InitialMemorySize;
Context.MemoryBase = InitialMemory; Context.MemoryBase = InitialMemory;
Context.WindowWidth = MainWindow.Width; Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
Context.WindowHeight = MainWindow.Height;
// Platform functions // Platform functions
Context.GeneralWorkQueue = &WorkQueue; Context.GeneralWorkQueue = &WorkQueue;
@ -634,11 +633,7 @@ Context.PlatformReadEntireFile = Win32ReadEntireFile;
HandleWindowMessage(Message, &MainWindow, &InputQueue, &Mouse); HandleWindowMessage(Message, &MainWindow, &InputQueue, &Mouse);
} }
// TODO(Peter): We shouldn't need to do this translation. the platform layer knows about win32_windows. We should just make that the interface Context.WindowBounds = rect{v2{0, 0}, v2{(r32)MainWindow.Width, (r32)MainWindow.Height}};
// to all windows.
// TODO(Peter): Decide which we want to use, context or renderbuffer. Should only be one
Context.WindowWidth = MainWindow.Width;
Context.WindowHeight = MainWindow.Height;
RenderBuffer.ViewWidth = MainWindow.Width; RenderBuffer.ViewWidth = MainWindow.Width;
RenderBuffer.ViewHeight = MainWindow.Height; RenderBuffer.ViewHeight = MainWindow.Height;
Context.DeltaTime = LastFrameSecondsElapsed; Context.DeltaTime = LastFrameSecondsElapsed;

View File

@ -1,7 +1,12 @@
TODO FOLDHAUS TODO FOLDHAUS
YOU WERE IN THE MIDDLE OF Animation Timeline
- click to drag time marker
- drag ends of animation clips to change start and end times
-
Reimplement Node View
- probably want to take a fresh pass at nodes all together
Assembly -> SACN interface Assembly -> SACN interface
x you need to rebuild the map from leds -> universes x you need to rebuild the map from leds -> universes
@ -89,17 +94,14 @@ Resource Management
- Icons - Icons
Animation Animation
- timeline x timeline
- create clips that play x create clips that play
- clips can have parameters that drive them? - clips can have parameters that drive them?
- clips should have prerequesites - clips should have prerequesites
- - channels active - - channels active
- - patterns active in the channel - - patterns active in the channel
- - when a clip is playing, it should just take over the whole structure - - when a clip is playing, it should just take over the whole structure
Command Line
- select a channel/pattern
Optimization Optimization
- investigate the memory access pattern of the SACN / LED systems. Guessing they are very slow - investigate the memory access pattern of the SACN / LED systems. Guessing they are very slow
- look into why debug logging functions seems to incur a large hit on framrate - look into why debug logging functions seems to incur a large hit on framrate