timeline visualization
This commit is contained in:
parent
a19c2395ae
commit
df5346f514
@ -5,6 +5,9 @@ V_Ctx V = Zi;
|
|||||||
|
|
||||||
void V_Bootstrap(void)
|
void V_Bootstrap(void)
|
||||||
{
|
{
|
||||||
|
V.timeline.transient_markers_arena = AcquireArena(Gibi(64));
|
||||||
|
V.timeline.persistent_markers_arena = AcquireArena(Gibi(64));
|
||||||
|
V.timeline.show = 1;
|
||||||
DispatchWave(Lit("Vis"), 1, V_TickForever, 0);
|
DispatchWave(Lit("Vis"), 1, V_TickForever, 0);
|
||||||
OnExit(V_Shutdown);
|
OnExit(V_Shutdown);
|
||||||
}
|
}
|
||||||
@ -252,6 +255,27 @@ void V_DrawPoint(Vec2 p, Vec4 srgb)
|
|||||||
V_DrawShape(ui_shape, AffineIdentity, srgb, 24, V_DrawFlag_None);
|
V_DrawShape(ui_shape, AffineIdentity, srgb, 24, V_DrawFlag_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Timeline helpers
|
||||||
|
|
||||||
|
void V_PushTimelineMarker(i64 time_ns, Vec4 color, b32 transient)
|
||||||
|
{
|
||||||
|
if (!V.timeline.paused)
|
||||||
|
{
|
||||||
|
V_TimelineMarker *marker = 0;
|
||||||
|
if (transient)
|
||||||
|
{
|
||||||
|
marker = PushStruct(V.timeline.transient_markers_arena, V_TimelineMarker);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
marker = PushStruct(V.timeline.persistent_markers_arena, V_TimelineMarker);
|
||||||
|
}
|
||||||
|
marker->time_ns = time_ns;
|
||||||
|
marker->color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Theme
|
//~ Theme
|
||||||
|
|
||||||
@ -571,7 +595,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
frame->is_editing = prev_frame->is_editing;
|
frame->is_editing = prev_frame->is_editing;
|
||||||
frame->ui_debug = prev_frame->ui_debug;
|
frame->ui_debug = prev_frame->ui_debug;
|
||||||
frame->show_console = prev_frame->show_console;
|
frame->show_console = prev_frame->show_console;
|
||||||
frame->show_timeline = prev_frame->show_timeline;
|
|
||||||
frame->look = prev_frame->look;
|
frame->look = prev_frame->look;
|
||||||
frame->fire_presses = prev_frame->fire_presses;
|
frame->fire_presses = prev_frame->fire_presses;
|
||||||
frame->roll_presses = prev_frame->roll_presses;
|
frame->roll_presses = prev_frame->roll_presses;
|
||||||
@ -1671,6 +1694,12 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
// P_DebugDrawFrame(predict_frame);
|
// P_DebugDrawFrame(predict_frame);
|
||||||
|
|
||||||
// TODO: Extract information that occurred between first & last prediction, like bullet hits etc?
|
// TODO: Extract information that occurred between first & last prediction, like bullet hits etc?
|
||||||
|
|
||||||
|
V_PushTimelineMarker(predict_frame->time_ns, Color_Purple, 1);
|
||||||
|
if (predict_to != prev_frame_predict_to)
|
||||||
|
{
|
||||||
|
V_PushTimelineMarker(predict_frame->time_ns, Color_Purple, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1876,6 +1905,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
{
|
{
|
||||||
i64 delay_ns = SIM_TICK_INTERVAL_NS * interp_ratio;
|
i64 delay_ns = SIM_TICK_INTERVAL_NS * interp_ratio;
|
||||||
V.target_blend_time_ns = predict_frame->time_ns - delay_ns;
|
V.target_blend_time_ns = predict_frame->time_ns - delay_ns;
|
||||||
|
|
||||||
|
V_PushTimelineMarker(ack_frame->time_ns, Color_Cyan, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2029,6 +2060,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
f64 blend_t = (f64)(V.blend_time_ns - left_predict_frame->base_time_ns) / (f64)(right_predict_frame->base_time_ns - left_predict_frame->base_time_ns);
|
f64 blend_t = (f64)(V.blend_time_ns - left_predict_frame->base_time_ns) / (f64)(right_predict_frame->base_time_ns - left_predict_frame->base_time_ns);
|
||||||
|
|
||||||
|
|
||||||
|
V_PushTimelineMarker(V.blend_time_ns, Color_Yellow, 1);
|
||||||
|
V_PushTimelineMarker(V.target_blend_time_ns, Color_Red, 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (IsInf(blend_t))
|
if (IsInf(blend_t))
|
||||||
@ -2334,7 +2369,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
frame->shade_cursor = MulAffineVec2(frame->af.screen_to_shade, frame->screen_cursor);
|
frame->shade_cursor = MulAffineVec2(frame->af.screen_to_shade, frame->screen_cursor);
|
||||||
frame->world_cursor = MulAffineVec2(frame->af.screen_to_world, frame->screen_cursor);
|
frame->world_cursor = MulAffineVec2(frame->af.screen_to_world, frame->screen_cursor);
|
||||||
|
|
||||||
b32 show_editor_ui = TweakBool("Show editor UI", 1);
|
b32 show_editor_ui = TweakBool("Show editor UI", 0);
|
||||||
|
|
||||||
frame->world_selection_start = frame->world_cursor;
|
frame->world_selection_start = frame->world_cursor;
|
||||||
if (frame->is_editing)
|
if (frame->is_editing)
|
||||||
@ -4572,64 +4607,59 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Build timeline debug UI
|
//- Build timeline debug UI
|
||||||
|
|
||||||
if (frame->show_timeline)
|
{
|
||||||
|
// FIXME: Remove this
|
||||||
|
f64 timeline_span_seconds = TweakFloat("Timeline span", 1, 0.01, 5);
|
||||||
|
i64 timeline_span_ns = NsFromSeconds(timeline_span_seconds);
|
||||||
|
PERSIST i64 last_timeline_reset_ns = 0;
|
||||||
|
PERSIST i64 timeline_start_ns = 0;
|
||||||
|
PERSIST i64 current_marker_time_ns = 0;
|
||||||
|
|
||||||
|
// Current frame time marker
|
||||||
|
if (!V.timeline.paused)
|
||||||
|
{
|
||||||
|
current_marker_time_ns = frame->time_ns - last_timeline_reset_ns + timeline_start_ns;
|
||||||
|
}
|
||||||
|
V_PushTimelineMarker(current_marker_time_ns, Color_White, 1);
|
||||||
|
|
||||||
|
b32 locked = frame->held_buttons[Button_R];
|
||||||
|
b32 paused = frame->held_buttons[Button_E];
|
||||||
|
V.timeline.locked = locked;
|
||||||
|
V.timeline.paused = paused;
|
||||||
|
|
||||||
|
i64 reset_span_ns = timeline_span_ns;
|
||||||
|
if (locked)
|
||||||
|
{
|
||||||
|
reset_span_ns *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!paused && frame->time_ns - last_timeline_reset_ns > reset_span_ns)
|
||||||
|
{
|
||||||
|
last_timeline_reset_ns = frame->time_ns;
|
||||||
|
timeline_start_ns = ack_frame->time_ns;
|
||||||
|
ResetArena(V.timeline.persistent_markers_arena);
|
||||||
|
}
|
||||||
|
if (V.timeline.show)
|
||||||
{
|
{
|
||||||
UI_Key timeline_key = UI_KeyF("Timeline box");
|
UI_Key timeline_key = UI_KeyF("Timeline box");
|
||||||
|
|
||||||
|
UI_Size timeline_width = UI_FNT(120, 1);
|
||||||
|
UI_Size timeline_height = UI_FNT(2, 1);
|
||||||
|
|
||||||
// FIXME: Remove this
|
|
||||||
i64 timeline_span_ns = NsFromSeconds(10);
|
|
||||||
PERSIST i64 last_timeline_switch_ns = 0;
|
|
||||||
PERSIST i64 timeline_start_ns = 0;
|
|
||||||
|
|
||||||
if (frame->time_ns - last_timeline_switch_ns > timeline_span_ns)
|
|
||||||
{
|
|
||||||
last_timeline_switch_ns = frame->time_ns;
|
|
||||||
timeline_start_ns = ack_frame->time_ns;
|
|
||||||
}
|
|
||||||
|
|
||||||
UI_Size timeline_width = UI_FNT(80, 1);
|
|
||||||
UI_Size timeline_height = UI_FNT(2.5, 1);
|
|
||||||
Vec4 tmld_bg = Color_Black;
|
Vec4 tmld_bg = Color_Black;
|
||||||
f32 timeline_opacity = 0.75;
|
|
||||||
Vec2 timeline_pos = VEC2(frame->screen_dims.x * 0.5, frame->screen_dims.y * 0.25);
|
Vec2 timeline_pos = VEC2(frame->screen_dims.x * 0.5, frame->screen_dims.y * 0.25);
|
||||||
|
|
||||||
//- Push markers
|
f32 timeline_opacity = 0.75;
|
||||||
Struct(TimelineMarker)
|
f32 marker_opacity = 0.75;
|
||||||
{
|
|
||||||
TimelineMarker *next;
|
|
||||||
i64 time_ns;
|
|
||||||
Vec4 color;
|
|
||||||
};
|
|
||||||
TimelineMarker *first_marker = 0;
|
|
||||||
TimelineMarker *last_marker = 0;
|
|
||||||
{
|
|
||||||
// Now frame time
|
|
||||||
// {
|
|
||||||
// TimelineMarker *marker = PushStruct(frame->arena, TimelineMarker);
|
|
||||||
// SllQueuePush(first_marker, last_marker, marker);
|
|
||||||
// marker->color = Color_White;
|
|
||||||
// marker->time_ns = frame->time_ns;
|
|
||||||
// }
|
|
||||||
// Ack frame time
|
|
||||||
{
|
|
||||||
TimelineMarker *marker = PushStruct(frame->arena, TimelineMarker);
|
|
||||||
SllQueuePush(first_marker, last_marker, marker);
|
|
||||||
marker->color = Color_Yellow;
|
|
||||||
marker->time_ns = ack_frame->time_ns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// i64 timeline_span_ns = NsFromSeconds(10);
|
// i64 timeline_span_ns = NsFromSeconds(10);
|
||||||
i64 timeline_span_ns = NsFromSeconds(1);
|
|
||||||
i64 timeline_start_ns = (frame->time_ns / timeline_span_ns) * timeline_span_ns;
|
|
||||||
|
|
||||||
i64 timeline_end_ns = timeline_start_ns + timeline_span_ns;
|
i64 timeline_end_ns = timeline_start_ns + timeline_span_ns;
|
||||||
|
|
||||||
UI_Size marker_width = UI_FNT(0.5, 1);
|
UI_Size transient_marker_width = UI_FNT(0.1, 1);
|
||||||
UI_Size marker_height = timeline_height;
|
UI_Size transient_marker_height = UI_FNT(2, 1);
|
||||||
|
|
||||||
|
UI_Size persistent_marker_width = UI_FNT(0.1, 1);
|
||||||
|
UI_Size persistent_marker_height = timeline_height;
|
||||||
|
|
||||||
UI_PushCP(UI_NilKey);
|
UI_PushCP(UI_NilKey);
|
||||||
{
|
{
|
||||||
@ -4643,32 +4673,85 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
UI_SetNext(Anchor, UI_Region_Center);
|
UI_SetNext(Anchor, UI_Region_Center);
|
||||||
UI_SetNext(FloatingPos, timeline_pos);
|
UI_SetNext(FloatingPos, timeline_pos);
|
||||||
UI_SetNext(BackgroundColor, tmld_bg);
|
UI_SetNext(BackgroundColor, tmld_bg);
|
||||||
UI_SetNext(Flags, UI_BoxFlag_Floating);
|
UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp);
|
||||||
UI_PushCP(UI_BuildRowEx(timeline_key));
|
UI_PushCP(UI_BuildRowEx(timeline_key));
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
UI_PopCP(UI_TopCP());
|
UI_PopCP(UI_TopCP());
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Build markers
|
Vec2 marker_offset = Zi;
|
||||||
for (TimelineMarker *marker = first_marker; marker; marker = marker->next)
|
if (locked)
|
||||||
{
|
{
|
||||||
f64 marker_ratio = (f64)(marker->time_ns - timeline_start_ns) / (f64)(timeline_end_ns - timeline_start_ns);
|
i64 offset_ns = current_marker_time_ns;
|
||||||
|
marker_offset.x = -((f64)(offset_ns - timeline_start_ns) / (f64)timeline_span_ns) * timeline_width.v + timeline_width.v * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Build markers
|
||||||
|
Arena *marker_arenas[] = {
|
||||||
|
V.timeline.transient_markers_arena,
|
||||||
|
V.timeline.persistent_markers_arena,
|
||||||
|
};
|
||||||
|
for (u64 marker_arena_idx = 0; marker_arena_idx < countof(marker_arenas); ++marker_arena_idx)
|
||||||
|
{
|
||||||
|
Arena *marker_arena = marker_arenas[marker_arena_idx];
|
||||||
|
u64 markers_count = ArenaCount(marker_arena, V_TimelineMarker);
|
||||||
|
b32 is_transient = marker_arena == V.timeline.transient_markers_arena;
|
||||||
|
V_TimelineMarker *markers = ArenaFirst(marker_arena, V_TimelineMarker);
|
||||||
|
for (u64 marker_idx = 0; marker_idx < markers_count; ++marker_idx)
|
||||||
|
{
|
||||||
|
V_TimelineMarker *marker = &markers[marker_idx];
|
||||||
|
|
||||||
|
UI_Size width = persistent_marker_width;
|
||||||
|
UI_Size height = persistent_marker_height;
|
||||||
|
if (is_transient)
|
||||||
|
{
|
||||||
|
width = transient_marker_width;
|
||||||
|
height = transient_marker_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec4 marker_color = marker->color;
|
||||||
|
|
||||||
|
f64 marker_ratio = (f64)(marker->time_ns - timeline_start_ns) / (f64)timeline_span_ns;
|
||||||
Vec2 marker_pos = timeline_pos;
|
Vec2 marker_pos = timeline_pos;
|
||||||
|
if (is_transient)
|
||||||
|
{
|
||||||
|
marker_pos.x += -timeline_width.v * 0.5 - width.v * 0.5;
|
||||||
|
marker_pos.y -= timeline_height.v * 0.5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
marker_pos.x += -timeline_width.v * 0.5 - width.v * 0.5;
|
||||||
|
marker_pos.y += timeline_height.v * 0.5;
|
||||||
|
}
|
||||||
marker_pos.x += marker_ratio * timeline_width.v;
|
marker_pos.x += marker_ratio * timeline_width.v;
|
||||||
|
|
||||||
UI_SetNext(Flags, UI_BoxFlag_Floating);
|
marker_pos = AddVec2(marker_pos, marker_offset);
|
||||||
UI_SetNext(BackgroundColor, marker->color);
|
|
||||||
|
Vec4 tint = UI_Top(Tint);
|
||||||
|
tint.a *= marker_opacity;
|
||||||
|
|
||||||
|
UI_SetNext(Tint, tint);
|
||||||
|
UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp);
|
||||||
|
UI_SetNext(BackgroundColor, marker_color);
|
||||||
UI_SetNext(Anchor, UI_Region_Center);
|
UI_SetNext(Anchor, UI_Region_Center);
|
||||||
UI_SetNext(Width, marker_width);
|
UI_SetNext(Width, width);
|
||||||
UI_SetNext(Height, marker_height);
|
UI_SetNext(Height, height);
|
||||||
UI_SetNext(FloatingPos, marker_pos);
|
UI_SetNext(FloatingPos, marker_pos);
|
||||||
UI_BuildBox();
|
UI_BuildBox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
UI_PopCP(UI_TopCP());
|
UI_PopCP(UI_TopCP());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!paused)
|
||||||
|
{
|
||||||
|
ResetArena(V.timeline.transient_markers_arena);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Build scoreboard UI
|
//- Build scoreboard UI
|
||||||
@ -5078,8 +5161,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
case V_CmdKind_toggle_timeline:
|
case V_CmdKind_toggle_timeline:
|
||||||
{
|
{
|
||||||
b32 new = !frame->show_timeline;
|
b32 new = !V.timeline.show;
|
||||||
frame->show_timeline = new;
|
V.timeline.show = new;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case V_CmdKind_toggle_fullscreen:
|
case V_CmdKind_toggle_fullscreen:
|
||||||
|
|||||||
@ -216,6 +216,15 @@ Enum(V_DrawFlag)
|
|||||||
V_DrawFlag_Line = (1 << 0),
|
V_DrawFlag_Line = (1 << 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Timeline types
|
||||||
|
|
||||||
|
Struct(V_TimelineMarker)
|
||||||
|
{
|
||||||
|
Vec4 color;
|
||||||
|
i64 time_ns;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ State types
|
//~ State types
|
||||||
|
|
||||||
@ -261,6 +270,15 @@ Struct(V_Ctx)
|
|||||||
P_EntKey player_key;
|
P_EntKey player_key;
|
||||||
P_EntKey follow_key;
|
P_EntKey follow_key;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
b32 show;
|
||||||
|
b32 paused;
|
||||||
|
b32 locked;
|
||||||
|
Arena *transient_markers_arena;
|
||||||
|
Arena *persistent_markers_arena;
|
||||||
|
} timeline;
|
||||||
|
|
||||||
i64 panels_count;
|
i64 panels_count;
|
||||||
i64 windows_count;
|
i64 windows_count;
|
||||||
V_Panel *root_panel;
|
V_Panel *root_panel;
|
||||||
@ -311,6 +329,11 @@ void V_DrawLine(Vec2 p0, Vec2 p1, Vec4 srgb);
|
|||||||
void V_DrawRect(Rng2 rect, Vec4 srgb, V_DrawFlag flags);
|
void V_DrawRect(Rng2 rect, Vec4 srgb, V_DrawFlag flags);
|
||||||
void V_DrawPoint(Vec2 p, Vec4 srgb);
|
void V_DrawPoint(Vec2 p, Vec4 srgb);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Timeline helpers
|
||||||
|
|
||||||
|
void V_PushTimelineMarker(i64 time_ns, Vec4 color, b32 transient);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Theme
|
//~ Theme
|
||||||
|
|
||||||
|
|||||||
@ -229,8 +229,8 @@ Enum(V_SelectionMode)
|
|||||||
|
|
||||||
Enum(V_EditMode)
|
Enum(V_EditMode)
|
||||||
{
|
{
|
||||||
V_EditMode_Tile,
|
|
||||||
V_EditMode_Prefab,
|
V_EditMode_Prefab,
|
||||||
|
V_EditMode_Tile,
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(V_Affines)
|
Struct(V_Affines)
|
||||||
@ -283,7 +283,6 @@ Struct(V_SharedFrame)
|
|||||||
b32 is_editing;
|
b32 is_editing;
|
||||||
b32 ui_debug;
|
b32 ui_debug;
|
||||||
b32 show_console;
|
b32 show_console;
|
||||||
b32 show_timeline;
|
|
||||||
b32 is_selecting;
|
b32 is_selecting;
|
||||||
b32 is_panning;
|
b32 is_panning;
|
||||||
b32 has_mouse_focus;
|
b32 has_mouse_focus;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user