editor camera keyboard navigation

This commit is contained in:
jacob 2025-12-18 13:20:37 -06:00
parent 767be8cf03
commit ec0f11d220
4 changed files with 59 additions and 28 deletions

View File

@ -452,27 +452,39 @@ void V_TickForever(WaveLaneCtx *lane)
frame->draw_cursor = MulXformV2(frame->ui_to_draw_xf, frame->ui_cursor); frame->draw_cursor = MulXformV2(frame->ui_to_draw_xf, frame->ui_cursor);
frame->world_cursor = MulXformV2(frame->ui_to_world_xf, frame->ui_cursor); frame->world_cursor = MulXformV2(frame->ui_to_world_xf, frame->ui_cursor);
frame->ui_selection_start = frame->ui_cursor; frame->world_selection_start = frame->world_cursor;
if (frame->is_editing) if (frame->is_editing)
{ {
b32 m1_held = frame->held_buttons[Button_M1];
b32 m2_held = frame->held_buttons[Button_M2];
frame->selection_mode = V_SelectionMode_Tile; frame->selection_mode = V_SelectionMode_Tile;
frame->is_selecting = frame->held_buttons[Button_M1]; if (m1_held)
{
frame->is_selecting = 1;
frame->equipped_tile = S_TileKind_Floor;
}
else if (m2_held)
{
frame->is_selecting = 1;
frame->equipped_tile = S_TileKind_None;
}
if (frame->is_selecting && last_frame->is_selecting) if (frame->is_selecting && last_frame->is_selecting)
{ {
frame->ui_selection_start = last_frame->ui_selection_start; frame->world_selection_start = last_frame->world_selection_start;
} }
} }
frame->ui_selection.p0.x = MinF32(last_frame->ui_cursor.x, last_frame->ui_selection_start.x); frame->world_selection.p0.x = MinF32(frame->world_cursor.x, frame->world_selection_start.x);
frame->ui_selection.p0.y = MinF32(last_frame->ui_cursor.y, last_frame->ui_selection_start.y); frame->world_selection.p0.y = MinF32(frame->world_cursor.y, frame->world_selection_start.y);
frame->ui_selection.p1.x = MaxF32(last_frame->ui_cursor.x, last_frame->ui_selection_start.x); frame->world_selection.p1.x = MaxF32(frame->world_cursor.x, frame->world_selection_start.x);
frame->ui_selection.p1.y = MaxF32(last_frame->ui_cursor.y, last_frame->ui_selection_start.y); frame->world_selection.p1.y = MaxF32(frame->world_cursor.y, frame->world_selection_start.y);
frame->draw_selection.p0 = MulXformV2(last_frame->ui_to_draw_xf, frame->ui_selection.p0); frame->ui_selection.p0 = MulXformV2(frame->world_to_ui_xf, frame->world_selection.p0);
frame->draw_selection.p1 = MulXformV2(last_frame->ui_to_draw_xf, frame->ui_selection.p1); frame->ui_selection.p1 = MulXformV2(frame->world_to_ui_xf, frame->world_selection.p1);
frame->world_selection.p0 = MulXformV2(last_frame->ui_to_world_xf, frame->ui_selection.p0); frame->draw_selection.p0 = MulXformV2(frame->world_to_draw_xf, frame->world_selection.p0);
frame->world_selection.p1 = MulXformV2(last_frame->ui_to_world_xf, frame->ui_selection.p1); frame->draw_selection.p1 = MulXformV2(frame->world_to_draw_xf, frame->world_selection.p1);
////////////////////////////// //////////////////////////////
//- Place tiles //- Place tiles
@ -483,14 +495,15 @@ void V_TickForever(WaveLaneCtx *lane)
{ {
if (last_frame->selection_mode == V_SelectionMode_Tile) if (last_frame->selection_mode == V_SelectionMode_Tile)
{ {
/* TODO: Fix clamp when both start & end are outside of world */
Rng2I32 tile_range = Zi; Rng2I32 tile_range = Zi;
tile_range.p0 = S_TilePosFromWorldPos(frame->world_selection.p0); tile_range.p0 = S_TilePosFromWorldPos(last_frame->world_selection.p0);
tile_range.p1 = S_TilePosFromWorldPos(frame->world_selection.p1); tile_range.p1 = S_TilePosFromWorldPos(last_frame->world_selection.p1);
tile_range.p1 = AddVec2I32(tile_range.p1, VEC2I32(1, 1)); tile_range.p1 = AddVec2I32(tile_range.p1, VEC2I32(1, 1));
S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Tile); S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Tile);
cmd->tile_placement.placement_kind = S_TilePlacementKind_Range; cmd->tile_placement.placement_kind = S_TilePlacementKind_Range;
cmd->tile_placement.tile_kind = S_TileKind_Floor; cmd->tile_placement.tile_kind = last_frame->equipped_tile;
cmd->tile_placement.range = tile_range; cmd->tile_placement.range = tile_range;
} }
} }
@ -696,11 +709,11 @@ void V_TickForever(WaveLaneCtx *lane)
case V_CmdKind_spawn: case V_CmdKind_spawn:
{ {
S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Tile); // S_Cmd *cmd = V_PushSimCmd(S_CmdKind_Tile);
cmd->tile_placement.placement_kind = S_TilePlacementKind_Range; // cmd->tile_placement.placement_kind = S_TilePlacementKind_Range;
cmd->tile_placement.tile_kind = S_TileKind_Wall; // cmd->tile_placement.tile_kind = S_TileKind_Wall;
cmd->tile_placement.range.p0 = VEC2I32(100, 100); // cmd->tile_placement.range.p0 = VEC2I32(100, 100);
cmd->tile_placement.range.p1 = VEC2I32(110, 110); // cmd->tile_placement.range.p1 = VEC2I32(110, 110);
// cmd->tile_placement.range.p0 = VEC2I32(2, 2); // cmd->tile_placement.range.p0 = VEC2I32(2, 2);
// cmd->tile_placement.range.p1 = VEC2I32(5, 5); // cmd->tile_placement.range.p1 = VEC2I32(5, 5);
} break; } break;
@ -710,7 +723,6 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Compute movement & look //- Compute movement & look
if (!frame->is_editing)
{ {
Vec2 move = Zi; Vec2 move = Zi;
{ {
@ -725,8 +737,19 @@ void V_TickForever(WaveLaneCtx *lane)
Vec2 center = MulXformV2(player->xf, player->local_shape.centroid); Vec2 center = MulXformV2(player->xf, player->local_shape.centroid);
look = SubVec2(frame->world_cursor, center); look = SubVec2(frame->world_cursor, center);
} }
frame->move = move; if (frame->is_editing)
frame->look = look; {
if (!frame->is_panning)
{
f32 edit_move_speed = 15.0 * MaxF32(frame->edit_camera_zoom, min_zoom);
frame->edit_camera_pos = AddVec2(frame->edit_camera_pos, MulVec2(move, edit_move_speed * frame->dt));
}
}
else
{
frame->move = move;
frame->look = look;
}
} }
/* Push control cmd */ /* Push control cmd */
@ -830,6 +853,8 @@ void V_TickForever(WaveLaneCtx *lane)
params.draw_to_world_xf = frame->draw_to_world_xf; params.draw_to_world_xf = frame->draw_to_world_xf;
params.selection_mode = frame->selection_mode; params.selection_mode = frame->selection_mode;
params.equipped_tile = frame->equipped_tile;
params.ui_cursor = frame->ui_cursor; params.ui_cursor = frame->ui_cursor;
params.draw_cursor = frame->draw_cursor; params.draw_cursor = frame->draw_cursor;
params.world_cursor = frame->world_cursor; params.world_cursor = frame->world_cursor;

View File

@ -111,12 +111,13 @@ Struct(V_Frame)
/* Editor state */ /* Editor state */
V_EditMode edit_mode; V_EditMode edit_mode;
S_TileKind equipped_tile;
/* Editor */ /* Editor */
b32 is_selecting; b32 is_selecting;
b32 is_panning; b32 is_panning;
V_SelectionMode selection_mode; V_SelectionMode selection_mode;
Vec2 ui_selection_start; Vec2 world_selection_start;
Vec2 edit_camera_pos; Vec2 edit_camera_pos;
f32 edit_camera_zoom; f32 edit_camera_zoom;

View File

@ -19,6 +19,8 @@ Struct(V_DParams)
Xform draw_to_world_xf; Xform draw_to_world_xf;
V_SelectionMode selection_mode; V_SelectionMode selection_mode;
S_TileKind equipped_tile;
Vec2 ui_cursor; Vec2 ui_cursor;
Vec2 draw_cursor; Vec2 draw_cursor;
Vec2 world_cursor; Vec2 world_cursor;

View File

@ -218,15 +218,18 @@ VertexShader(V_OverlayVS, V_OverlayPSInput)
PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input) PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input)
{ {
V_DParams params = G_Dereference<V_DParams>(V_ShaderConst_Params)[0]; V_DParams params = G_Dereference<V_DParams>(V_ShaderConst_Params)[0];
Texture2D<uint> tiles = G_Dereference<uint>(params.tiles);
Vec2 screen_pos = input.sv_position.xy; Vec2 screen_pos = input.sv_position.xy;
Vec4 result = 0; Vec4 result = 0;
Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(screen_pos, 1)); Vec2 world_pos = mul(params.draw_to_world_xf, Vec3(screen_pos, 1));
Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos); Vec2I32 tile_pos = S_TilePosFromWorldPos(world_pos);
S_TileKind equipped_tile = params.equipped_tile;
f32 half_thickness = 1; f32 half_thickness = 1;
Vec4 border_color = LinearFromSrgb(Vec4(1, 1, 1, 1)); Vec4 border_color = LinearFromSrgb(Vec4(1, 1, 1, 1));
// Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.4, 0.4, 0.25)); // Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.4, 0.4, 0.25));
Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.8, 0.4, 0.6)); Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.8, 0.4, 0.6));
Rng2 screen_selection = params.draw_selection; Rng2 screen_selection = params.draw_selection;
@ -245,11 +248,11 @@ PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input)
dist = min(dist, screen_selection.p1.y - screen_pos.y); dist = min(dist, screen_selection.p1.y - screen_pos.y);
dist = -dist; dist = -dist;
if (dist > -half_thickness && dist < half_thickness) // if (dist > -half_thickness && dist < half_thickness)
{ // {
result = border_color; // result = border_color;
} // }
else // else
{ {
if (world_pos.x > -(S_WorldSize / 2) && if (world_pos.x > -(S_WorldSize / 2) &&
world_pos.y > -(S_WorldSize / 2) && world_pos.y > -(S_WorldSize / 2) &&