edit mode
This commit is contained in:
parent
0efcc35696
commit
81990f81a4
@ -889,7 +889,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_ResourceDesc desc)
|
||||
/* Create d3d heap */
|
||||
{
|
||||
D3D12_HEAP_DESC d3d_desc = Zi;
|
||||
d3d_desc.SizeInBytes = Mebi(512);
|
||||
d3d_desc.SizeInBytes = Mebi(256);
|
||||
if (heap_kind == G_D12_ResourceHeapKind_Cpu)
|
||||
{
|
||||
d3d_desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM;
|
||||
|
||||
@ -43,6 +43,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Struct(Persist)
|
||||
{
|
||||
V_CommandsWidget commands_widget;
|
||||
|
||||
b32 edit_mode;
|
||||
Vec2 edit_camera_pos;
|
||||
f32 edit_camera_zoom;
|
||||
|
||||
b32 ui_debug;
|
||||
b32 show_command_palette;
|
||||
b32 show_console;
|
||||
@ -50,8 +55,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Persist persist = Zi;
|
||||
String window_restore = Zi;
|
||||
|
||||
Button held_buttons[Button_Count] = Zi;
|
||||
|
||||
/* Init shortcuts */
|
||||
u64 shortcut_bins_count = 1024;
|
||||
V_ShortcutBin *shortcut_bins = PushStructs(perm, V_ShortcutBin, shortcut_bins_count);
|
||||
@ -137,6 +140,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
ResetArena(frame->dvert_idxs_arena);
|
||||
G_ResetArena(frame->cl, frame->gpu_arena);
|
||||
|
||||
CopyBytes(frame->held_buttons, last_frame->held_buttons, sizeof(frame->held_buttons));
|
||||
|
||||
frame->time_ns = TimeNs();
|
||||
frame->tick = last_frame->tick + 1;
|
||||
frame->dt_ns = frame->time_ns - last_frame->time_ns;
|
||||
@ -222,8 +227,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_Report vis_rep = UI_ReportFromKey(vis_box);
|
||||
draw_size = RoundVec2ToI32(DimsFromRng2(vis_rep.screen_rect));
|
||||
}
|
||||
draw_size.x = MaxI32(draw_size.x, 1);
|
||||
draw_size.y = MaxI32(draw_size.y, 1);
|
||||
draw_size.x = MaxI32(draw_size.x, 64);
|
||||
draw_size.y = MaxI32(draw_size.y, 64);
|
||||
|
||||
//////////////////////////////
|
||||
//- Pop sim output
|
||||
@ -247,27 +252,127 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
V.lookup = S_LookupFromWorld(V.world_arena, V.world);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Process controller events into vis cmds
|
||||
|
||||
u64 cmds_count = 0;
|
||||
V_CmdNode *first_cmd_node = 0;
|
||||
V_CmdNode *last_cmd_node = 0;
|
||||
|
||||
if (!window_frame.has_focus)
|
||||
{
|
||||
ZeroStructs(frame->held_buttons, countof(frame->held_buttons));
|
||||
}
|
||||
for (u64 i = 0; i < window_frame.controller_events.count; ++i)
|
||||
{
|
||||
ControllerEvent cev = window_frame.controller_events.events[i];
|
||||
b32 down = cev.kind == ControllerEventKind_ButtonDown;
|
||||
b32 up = cev.kind == ControllerEventKind_ButtonUp;
|
||||
if (down || up)
|
||||
{
|
||||
V_Hotkey hotkey = Zi;
|
||||
hotkey.button = cev.button;
|
||||
hotkey.ctrl = frame->held_buttons[Button_Ctrl];
|
||||
hotkey.shift = frame->held_buttons[Button_Shift];
|
||||
hotkey.alt = frame->held_buttons[Button_Alt];
|
||||
{
|
||||
u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey));
|
||||
V_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
|
||||
V_Shortcut *shortcut = bin->first;
|
||||
for (; shortcut; shortcut = shortcut->next_in_bin)
|
||||
{
|
||||
if (shortcut->hotkey_hash == hotkey_hash && MatchStruct(&shortcut->hotkey, &hotkey))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shortcut != 0 && down)
|
||||
{
|
||||
V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode);
|
||||
cmd_node->cmd.name = shortcut->cmd_name;
|
||||
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
|
||||
++cmds_count;
|
||||
}
|
||||
}
|
||||
frame->held_buttons[hotkey.button] = down;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Update edit mode camera position
|
||||
|
||||
f32 zoom_rate = 2;
|
||||
f32 min_zoom = 0.03;
|
||||
f32 max_zoom = 50.0;
|
||||
f32 world_size = 256;
|
||||
// if (persist.edit_mode)
|
||||
// {
|
||||
// if (V.is_panning)
|
||||
// {
|
||||
// Vec2 pan_diff = SubVec2(V.pan_end, V.pan_start);
|
||||
// persist.edit_camera_pos = pan_diff;
|
||||
// }
|
||||
// }
|
||||
if (persist.edit_camera_zoom <= 0)
|
||||
{
|
||||
persist.edit_camera_zoom = 1;
|
||||
}
|
||||
persist.edit_camera_zoom = ClampF32(persist.edit_camera_zoom, min_zoom, max_zoom);
|
||||
persist.edit_camera_pos.x = ClampF32(persist.edit_camera_pos.x, -world_size / 2, world_size / 2);
|
||||
persist.edit_camera_pos.y = ClampF32(persist.edit_camera_pos.y, -world_size / 2, world_size / 2);
|
||||
|
||||
//////////////////////////////
|
||||
//- Initialize camera
|
||||
|
||||
f32 meters_per_draw_width = 20;
|
||||
|
||||
{
|
||||
f32 lerp_ratio = 20 * frame->dt;
|
||||
Vec2 look_ratio = Zi;
|
||||
look_ratio.y = 0.25;
|
||||
look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
||||
|
||||
Vec2 target_camera_pos = Zi;
|
||||
f32 target_camera_zoom = 1;
|
||||
f32 pos_lerp_ratio = 1;
|
||||
f32 zoom_lerp_ratio = 1;
|
||||
if (last_frame->tick > 0)
|
||||
{
|
||||
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
||||
target_camera_pos = MulXformV2(player->xf, player->local_shape.centroid);
|
||||
target_camera_pos = AddVec2(target_camera_pos, MulVec2Vec2(player->look, look_ratio));
|
||||
if (persist.edit_mode)
|
||||
{
|
||||
pos_lerp_ratio = 30.0 * frame->dt;
|
||||
zoom_lerp_ratio = 30.0 * frame->dt;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos_lerp_ratio = 20.0 * frame->dt;
|
||||
zoom_lerp_ratio = 20.0 * frame->dt;
|
||||
}
|
||||
}
|
||||
|
||||
frame->camera_pos = LerpVec2(last_frame->camera_pos, target_camera_pos, lerp_ratio);
|
||||
frame->camera_zoom = LerpF32(last_frame->camera_zoom, target_camera_zoom, lerp_ratio);
|
||||
|
||||
// if (persist.edit_mode && V.is_panning)
|
||||
// {
|
||||
// persist.edit_camera_pos = V.pan_begin;
|
||||
// }
|
||||
|
||||
Vec2 target_camera_pos = persist.edit_camera_pos;
|
||||
f32 target_camera_zoom = persist.edit_camera_zoom;
|
||||
{
|
||||
if (!persist.edit_mode)
|
||||
{
|
||||
Vec2 look_ratio = Zi;
|
||||
look_ratio.y = 0.25;
|
||||
look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
||||
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
||||
target_camera_pos = MulXformV2(player->xf, player->local_shape.centroid);
|
||||
target_camera_pos = AddVec2(target_camera_pos, MulVec2Vec2(player->look, look_ratio));
|
||||
target_camera_zoom = 1;
|
||||
}
|
||||
if (target_camera_zoom <= 0)
|
||||
{
|
||||
target_camera_zoom = 1;
|
||||
}
|
||||
}
|
||||
|
||||
frame->camera_pos = LerpVec2(last_frame->camera_pos, target_camera_pos, pos_lerp_ratio);
|
||||
frame->camera_zoom = LerpF32(last_frame->camera_zoom, target_camera_zoom, zoom_lerp_ratio);
|
||||
|
||||
frame->camera_zoom = ClampF32(frame->camera_zoom, min_zoom, max_zoom);
|
||||
|
||||
meters_per_draw_width /= frame->camera_zoom;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -306,52 +411,6 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2 draw_cursor = MulXformV2(ui_to_draw_xf, ui_cursor);
|
||||
Vec2 world_cursor = MulXformV2(ui_to_world_xf, ui_cursor);
|
||||
|
||||
//////////////////////////////
|
||||
//- Process controller events into vis cmds
|
||||
|
||||
u64 cmds_count = 0;
|
||||
V_CmdNode *first_cmd_node = 0;
|
||||
V_CmdNode *last_cmd_node = 0;
|
||||
|
||||
if (!window_frame.has_focus)
|
||||
{
|
||||
ZeroStructs(held_buttons, countof(held_buttons));
|
||||
}
|
||||
for (u64 i = 0; i < window_frame.controller_events.count; ++i)
|
||||
{
|
||||
ControllerEvent cev = window_frame.controller_events.events[i];
|
||||
b32 down = cev.kind == ControllerEventKind_ButtonDown;
|
||||
b32 up = cev.kind == ControllerEventKind_ButtonUp;
|
||||
if (down || up)
|
||||
{
|
||||
V_Hotkey hotkey = Zi;
|
||||
hotkey.button = cev.button;
|
||||
hotkey.ctrl = held_buttons[Button_Ctrl];
|
||||
hotkey.shift = held_buttons[Button_Shift];
|
||||
hotkey.alt = held_buttons[Button_Alt];
|
||||
{
|
||||
u64 hotkey_hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey));
|
||||
V_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
|
||||
V_Shortcut *shortcut = bin->first;
|
||||
for (; shortcut; shortcut = shortcut->next_in_bin)
|
||||
{
|
||||
if (shortcut->hotkey_hash == hotkey_hash && MatchStruct(&shortcut->hotkey, &hotkey))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shortcut != 0 && down)
|
||||
{
|
||||
V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode);
|
||||
cmd_node->cmd.name = shortcut->cmd_name;
|
||||
SllQueuePush(first_cmd_node, last_cmd_node, cmd_node);
|
||||
++cmds_count;
|
||||
}
|
||||
}
|
||||
held_buttons[hotkey.button] = down;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Build command palette
|
||||
|
||||
@ -382,7 +441,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Build console
|
||||
//- Build console UI
|
||||
|
||||
if (persist.show_console)
|
||||
{
|
||||
@ -391,7 +450,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Build debug info
|
||||
//- Build debug info UI
|
||||
|
||||
if (persist.show_console)
|
||||
{
|
||||
@ -421,9 +480,17 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_PopCP(UI_TopCP());
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Build edit mode UI
|
||||
|
||||
if (persist.edit_mode)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Process vis commands
|
||||
|
||||
i32 edit_zooms = 0;
|
||||
for (V_CmdNode *cmd_node = first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
||||
{
|
||||
String cmd_name = cmd_node->cmd.name;
|
||||
@ -450,6 +517,36 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
persist.show_command_palette = !persist.show_command_palette;
|
||||
} break;
|
||||
|
||||
case V_CmdKind_zoom_in:
|
||||
{
|
||||
if (persist.edit_mode)
|
||||
{
|
||||
edit_zooms += 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case V_CmdKind_zoom_out:
|
||||
{
|
||||
if (persist.edit_mode)
|
||||
{
|
||||
edit_zooms -= 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
case V_CmdKind_toggle_edit_mode:
|
||||
{
|
||||
b32 new = !persist.edit_mode;
|
||||
if (new)
|
||||
{
|
||||
LogInfoF("Enabled edit mode");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogInfoF("Disabled edit mode");
|
||||
}
|
||||
persist.edit_mode = new;
|
||||
} break;
|
||||
|
||||
case V_CmdKind_toggle_ui_debug:
|
||||
{
|
||||
persist.ui_debug = !persist.ui_debug;
|
||||
@ -485,6 +582,52 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Update edit camera
|
||||
|
||||
if (persist.edit_mode)
|
||||
{
|
||||
b32 pan_button = Button_M3;
|
||||
b32 old_is_panning = V.is_panning;
|
||||
V.is_panning = frame->held_buttons[pan_button] != 0;
|
||||
b32 is_begin_panning = V.is_panning && !old_is_panning;
|
||||
if (is_begin_panning)
|
||||
{
|
||||
V.ui_pan_begin_cursor = ui_cursor;
|
||||
}
|
||||
if (V.is_panning)
|
||||
{
|
||||
Vec2 ui_pan_diff = SubVec2(ui_cursor, V.ui_pan_begin_cursor);
|
||||
Vec2 world_pan_diff = MulXformBasisV2(ui_to_world_xf, ui_pan_diff);
|
||||
persist.edit_camera_pos = SubVec2(persist.edit_camera_pos, world_pan_diff);
|
||||
V.ui_pan_begin_cursor = ui_cursor;
|
||||
}
|
||||
persist.edit_camera_zoom *= PowF32(zoom_rate, edit_zooms);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Calculate movement & look
|
||||
|
||||
frame->look = last_frame->look;
|
||||
if (!persist.edit_mode)
|
||||
{
|
||||
Vec2 move = Zi;
|
||||
{
|
||||
if (frame->held_buttons[Button_A]) move.x -= 1;
|
||||
if (frame->held_buttons[Button_D]) move.x += 1;
|
||||
if (frame->held_buttons[Button_W]) move.y -= 1;
|
||||
if (frame->held_buttons[Button_S]) move.y += 1;
|
||||
}
|
||||
Vec2 look = Zi;
|
||||
{
|
||||
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
||||
Vec2 center = MulXformV2(player->xf, player->local_shape.centroid);
|
||||
look = SubVec2(world_cursor, center);
|
||||
}
|
||||
frame->move = move;
|
||||
frame->look = look;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Submit sim commands
|
||||
|
||||
@ -502,22 +645,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
cmd = &cmd_node->cmd;
|
||||
}
|
||||
cmd->kind = S_CmdKind_Control;
|
||||
Vec2 move = Zi;
|
||||
{
|
||||
if (held_buttons[Button_A]) move.x -= 1;
|
||||
if (held_buttons[Button_D]) move.x += 1;
|
||||
if (held_buttons[Button_W]) move.y -= 1;
|
||||
if (held_buttons[Button_S]) move.y += 1;
|
||||
}
|
||||
Vec2 look = Zi;
|
||||
{
|
||||
S_Ent *player = S_EntFromKey(&V.lookup, V.player_key);
|
||||
Vec2 center = MulXformV2(player->xf, player->local_shape.centroid);
|
||||
look = SubVec2(world_cursor, center);
|
||||
}
|
||||
cmd->target = V.player_key;
|
||||
cmd->move = move;
|
||||
cmd->look = look;
|
||||
cmd->move = frame->move;
|
||||
cmd->look = frame->look;
|
||||
}
|
||||
|
||||
/* Submit spawn cmds */
|
||||
@ -622,6 +752,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
params.background_color_a = LinearFromSrgb(VEC4(0.30, 0.30, 0.30, 1));
|
||||
params.background_color_b = LinearFromSrgb(VEC4(0.15, 0.15, 0.15, 1));
|
||||
params.x_axis_color = LinearFromSrgb(VEC4(0.75, 0, 0, 1));
|
||||
params.y_axis_color = LinearFromSrgb(VEC4(0, 0.75, 0, 1));
|
||||
params.bounds_color = LinearFromSrgb(VEC4(0.75, 0.75, 0, 1));
|
||||
|
||||
params.world_size = world_size;
|
||||
|
||||
params.world_to_draw_xf = world_to_draw_xf;
|
||||
params.draw_to_world_xf = draw_to_world_xf;
|
||||
|
||||
@ -5,6 +5,9 @@
|
||||
X(nop, NOP, V_CmdDescFlag_HideFromPalette, V_HOTKEY(0), ) \
|
||||
X(exit_program, Exit Program, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_Escape ) ) \
|
||||
X(toggle_command_palette, Toggle Command Palette, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \
|
||||
X(zoom_in, Zoom In, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_MWheelUp ), ) \
|
||||
X(zoom_out, Zoom Out, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_MWheelDown ), ) \
|
||||
X(toggle_edit_mode, Toggle Edit Mode, V_CmdDescFlag_None, V_HOTKEY( Button_F1 ), ) \
|
||||
X(toggle_ui_debug, Toggle UI Debug, V_CmdDescFlag_None, V_HOTKEY( Button_F5 ), ) \
|
||||
X(toggle_console, Toggle Developer Console, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent ), ) \
|
||||
X(toggle_fullscreen, Toggle Fullscreen Mode, V_CmdDescFlag_None, V_HOTKEY( Button_Enter, .alt = 1 ) ) \
|
||||
@ -80,9 +83,14 @@ Struct(V_Frame)
|
||||
Arena *dvert_idxs_arena;
|
||||
G_ArenaHandle gpu_arena;
|
||||
|
||||
Button held_buttons[Button_Count];
|
||||
|
||||
Vec2 camera_pos;
|
||||
f32 camera_zoom;
|
||||
|
||||
Vec2 move;
|
||||
Vec2 look;
|
||||
|
||||
i64 tick;
|
||||
i64 time_ns;
|
||||
i64 dt_ns;
|
||||
@ -97,6 +105,9 @@ Struct(V_Ctx)
|
||||
S_Lookup lookup;
|
||||
S_Key player_key;
|
||||
|
||||
b32 is_panning;
|
||||
Vec2 ui_pan_begin_cursor;
|
||||
|
||||
Atomic32 shutdown;
|
||||
Fence shutdown_complete;
|
||||
|
||||
|
||||
@ -16,6 +16,11 @@ Struct(V_DParams)
|
||||
|
||||
Vec4 background_color_a;
|
||||
Vec4 background_color_b;
|
||||
Vec4 x_axis_color;
|
||||
Vec4 y_axis_color;
|
||||
Vec4 bounds_color;
|
||||
|
||||
f32 world_size;
|
||||
|
||||
Xform world_to_draw_xf;
|
||||
Xform draw_to_world_xf;
|
||||
|
||||
@ -40,22 +40,45 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
result = colors[color_idx];
|
||||
}
|
||||
|
||||
/* Axis color */
|
||||
{
|
||||
f32 half_thickness = 1;
|
||||
Vec2 zero_screen = mul(params.world_to_draw_xf, Vec3(0, 0, 1));
|
||||
f32 x_dist = abs(target_pos.x - zero_screen.x);
|
||||
f32 y_dist = abs(target_pos.y - zero_screen.y);
|
||||
if (y_dist <= half_thickness)
|
||||
f32 half_bounds_size = params.world_size * 0.5;
|
||||
Vec2 bounds_screen_p0 = mul(params.world_to_draw_xf, Vec3(-half_bounds_size, -half_bounds_size, 1));
|
||||
Vec2 bounds_screen_p1 = mul(params.world_to_draw_xf, Vec3(half_bounds_size, half_bounds_size, 1));
|
||||
if (target_pos.x > (bounds_screen_p0.x - half_thickness) && target_pos.y > (bounds_screen_p0.y - half_thickness) &&
|
||||
target_pos.x < (bounds_screen_p1.x + half_thickness) && target_pos.y < (bounds_screen_p1.y + half_thickness))
|
||||
{
|
||||
result = Color_Red;
|
||||
}
|
||||
else if (x_dist <= half_thickness)
|
||||
{
|
||||
result = Color_Green;
|
||||
/* Axis color */
|
||||
{
|
||||
f32 half_thickness = 1;
|
||||
Vec2 zero_screen = mul(params.world_to_draw_xf, Vec3(0, 0, 1));
|
||||
f32 x_dist = abs(target_pos.x - zero_screen.x);
|
||||
f32 y_dist = abs(target_pos.y - zero_screen.y);
|
||||
if (y_dist <= half_thickness)
|
||||
{
|
||||
result = params.x_axis_color;
|
||||
}
|
||||
else if (x_dist <= half_thickness)
|
||||
{
|
||||
result = params.y_axis_color;
|
||||
}
|
||||
}
|
||||
/* World bounds color */
|
||||
{
|
||||
f32 bounds_dist = 100000;
|
||||
bounds_dist = min(bounds_dist, abs(target_pos.x - bounds_screen_p0.x));
|
||||
bounds_dist = min(bounds_dist, abs(target_pos.x - bounds_screen_p1.x));
|
||||
bounds_dist = min(bounds_dist, abs(target_pos.y - bounds_screen_p0.y));
|
||||
bounds_dist = min(bounds_dist, abs(target_pos.y - bounds_screen_p1.y));
|
||||
if (bounds_dist <= half_thickness)
|
||||
{
|
||||
result = params.bounds_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
target[target_pos] = result;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user