diff --git a/assets/textures/terrain/editing/connected_off.png b/assets/textures/terrain/editing/connected_off.png new file mode 100644 index 0000000..2c1e59e Binary files /dev/null and b/assets/textures/terrain/editing/connected_off.png differ diff --git a/assets/textures/terrain/editing/connected_off.png.import b/assets/textures/terrain/editing/connected_off.png.import new file mode 100644 index 0000000..25cf970 --- /dev/null +++ b/assets/textures/terrain/editing/connected_off.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c5j5v62f7p6qt" +path="res://.godot/imported/connected_off.png-9d4314286cb3dda8aeb51987f4722c68.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/terrain/editing/connected_off.png" +dest_files=["res://.godot/imported/connected_off.png-9d4314286cb3dda8aeb51987f4722c68.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/terrain/editing/connected_on.png b/assets/textures/terrain/editing/connected_on.png new file mode 100644 index 0000000..482ec8f Binary files /dev/null and b/assets/textures/terrain/editing/connected_on.png differ diff --git a/assets/textures/terrain/editing/connected_on.png.import b/assets/textures/terrain/editing/connected_on.png.import new file mode 100644 index 0000000..ae791fd --- /dev/null +++ b/assets/textures/terrain/editing/connected_on.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dsbovbbrtuv8f" +path="res://.godot/imported/connected_on.png-d142e6ffef231eda75d9207321617fb4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/terrain/editing/connected_on.png" +dest_files=["res://.godot/imported/connected_on.png-d142e6ffef231eda75d9207321617fb4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/terrain/editing/corner.png.import b/assets/textures/terrain/editing/corner.png.import index 99be1e5..a290bc6 100644 --- a/assets/textures/terrain/editing/corner.png.import +++ b/assets/textures/terrain/editing/corner.png.import @@ -31,4 +31,4 @@ process/normal_map_invert_y=false process/hdr_as_srgb=false process/hdr_clamp_exposure=false process/size_limit=0 -detect_3d/compress_to=1 +detect_3d/compress_to=0 diff --git a/assets/textures/terrain/editing/corner_paint.png b/assets/textures/terrain/editing/corner_paint.png new file mode 100644 index 0000000..e766872 Binary files /dev/null and b/assets/textures/terrain/editing/corner_paint.png differ diff --git a/assets/textures/terrain/editing/corner_paint.png.import b/assets/textures/terrain/editing/corner_paint.png.import new file mode 100644 index 0000000..94ca0dd --- /dev/null +++ b/assets/textures/terrain/editing/corner_paint.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dc0q2xn2cgcjw" +path="res://.godot/imported/corner_paint.png-d3f97054fffda3dc2896d8416d2182b9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/terrain/editing/corner_paint.png" +dest_files=["res://.godot/imported/corner_paint.png-d3f97054fffda3dc2896d8416d2182b9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/terrain/editing/flatten.png b/assets/textures/terrain/editing/flatten.png new file mode 100644 index 0000000..9e017ef Binary files /dev/null and b/assets/textures/terrain/editing/flatten.png differ diff --git a/assets/textures/terrain/editing/flatten.png.import b/assets/textures/terrain/editing/flatten.png.import new file mode 100644 index 0000000..dc9a3f7 --- /dev/null +++ b/assets/textures/terrain/editing/flatten.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bcb8w33ns56go" +path="res://.godot/imported/flatten.png-f2f312eef574983bc85e28cb99e262b2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/terrain/editing/flatten.png" +dest_files=["res://.godot/imported/flatten.png-f2f312eef574983bc85e28cb99e262b2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/terrain/editing/height_down.png b/assets/textures/terrain/editing/height_down.png new file mode 100644 index 0000000..fe207d1 Binary files /dev/null and b/assets/textures/terrain/editing/height_down.png differ diff --git a/assets/textures/terrain/editing/height_down.png.import b/assets/textures/terrain/editing/height_down.png.import new file mode 100644 index 0000000..caf8a8b --- /dev/null +++ b/assets/textures/terrain/editing/height_down.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://covyafauwthij" +path="res://.godot/imported/height_down.png-47ae6eeb5feb0ddf7bd952befb4351fe.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/terrain/editing/height_down.png" +dest_files=["res://.godot/imported/height_down.png-47ae6eeb5feb0ddf7bd952befb4351fe.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/terrain/editing/height_up.png b/assets/textures/terrain/editing/height_up.png new file mode 100644 index 0000000..4480636 Binary files /dev/null and b/assets/textures/terrain/editing/height_up.png differ diff --git a/assets/textures/terrain/editing/height_up.png.import b/assets/textures/terrain/editing/height_up.png.import new file mode 100644 index 0000000..a026188 --- /dev/null +++ b/assets/textures/terrain/editing/height_up.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dxbfohim13ti1" +path="res://.godot/imported/height_up.png-d84180c0cff17a8285e5e5cb8f54e819.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/terrain/editing/height_up.png" +dest_files=["res://.godot/imported/height_up.png-d84180c0cff17a8285e5e5cb8f54e819.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/terrain/editing/ModifierToggleButton.cs b/terrain/editing/ModifierToggleButton.cs new file mode 100644 index 0000000..02b9380 --- /dev/null +++ b/terrain/editing/ModifierToggleButton.cs @@ -0,0 +1,17 @@ +[Tool] +public partial class ModifierToggleButton : Button +{ + [Export] public Texture2D OnTexture { get; set; } + [Export] public Texture2D OffTexture { get; set; } + [Export] public Key ModifierKey { get; set; } + + + public override void _Ready() + => Toggled += (on) => Icon = on ? OnTexture : OffTexture; + + public override void _Input(InputEvent ev) + { + if ((ev is InputEventKey { Keycode: var key }) && (key == ModifierKey)) + ButtonPressed = !ButtonPressed; + } +} diff --git a/terrain/editing/TerrainEditingControls+Editing.cs b/terrain/editing/TerrainEditingControls+Editing.cs index e5c42ad..3539871 100644 --- a/terrain/editing/TerrainEditingControls+Editing.cs +++ b/terrain/editing/TerrainEditingControls+Editing.cs @@ -74,43 +74,43 @@ public partial class TerrainEditingControls _ => throw new InvalidOperationException(), }).ToHashSet(); - // TODO: Handle different tool modes, such as painting. - // TODO: Add a flatten tool mode: Flattens everything selected to nearest corner height. + // TODO: Handle different tool modes, such as flatten and painting. // TODO: Allow click-dragging which doesn't affect already changed tiles / corners. // TODO: Support undo and redo. - // TODO: Support "disconnected" mode which can create vertical cliffs. + // TODO: Make mesh generation generate vertical walls between disconnected corners. + // TODO: Use ArrayMesh instead of ImmediateMesh. // Raise / lower the terrain if left / right mouse button is pressed. - if ((mouse is InputEventMouseButton { ButtonIndex: var button, Pressed: true }) - && (button is MouseButton.Left or MouseButton.Right)) - { + if (mouse is InputEventMouseButton { ButtonIndex: MouseButton.Left, Pressed: true }) { GetViewport().SetInputAsHandled(); const float AdjustHeight = 0.5f; - var amount = (button == MouseButton.Left) - ? AdjustHeight : -AdjustHeight; - - // Find corners that are "connected" and should be raised. - var corners = new HashSet<(TilePos Position, Corner Corner)>(); - foreach (var pos in tiles) { - var tile2 = terrain.GetTile(pos); - foreach (var corner2 in Enum.GetValues()) { - var height = tile2.Height[corner2]; - foreach (var (neighborPos, neighborCorner) in GetNeighbors(pos, corner2)) { - if (tiles.Contains(neighborPos)) continue; - var neighborHeight = terrain.GetTile(neighborPos).Height[neighborCorner]; - if (neighborHeight == height) corners.Add((neighborPos, neighborCorner)); + var amount = UpDownToggle.ButtonPressed ? AdjustHeight : -AdjustHeight; + + // If the Connected toggle button is active, move "connected" corners. + // Connected corners are the ones that are at the same height as ones already being moved. + if (ConnectedToggle.ButtonPressed) { + var corners = new HashSet<(TilePos Position, Corner Corner)>(); + foreach (var pos in tiles) { + var tile2 = terrain.GetTile(pos); + foreach (var corner2 in Enum.GetValues()) { + var height = tile2.Height[corner2]; + foreach (var (neighborPos, neighborCorner) in GetNeighbors(pos, corner2)) { + if (tiles.Contains(neighborPos)) continue; + var neighborHeight = terrain.GetTile(neighborPos).Height[neighborCorner]; + if (neighborHeight == height) corners.Add((neighborPos, neighborCorner)); + } } } - } - // Raise connected corners. - foreach (var group in corners.GroupBy(e => e.Position, e => e.Corner)) { - var pos = group.Key; - var tile2 = terrain.GetTile(pos); - foreach (var corner2 in group) - tile2.Height[corner2] += amount; - terrain.SetTile(pos, tile2); + // Raise connected corners. + foreach (var group in corners.GroupBy(e => e.Position, e => e.Corner)) { + var pos = group.Key; + var tile2 = terrain.GetTile(pos); + foreach (var corner2 in group) + tile2.Height[corner2] += amount; + terrain.SetTile(pos, tile2); + } } // Raise selected tiles themselves. diff --git a/terrain/editing/TerrainEditingControls.cs b/terrain/editing/TerrainEditingControls.cs index 163b222..cd4bf7e 100644 --- a/terrain/editing/TerrainEditingControls.cs +++ b/terrain/editing/TerrainEditingControls.cs @@ -4,19 +4,26 @@ public partial class TerrainEditingControls { public (ToolMode , Button)[] ToolModeButtons { get; private set; } public (ToolShape, Button)[] ToolShapeButtons { get; private set; } - public Button[] PaintTextureButtons { get; private set; } public Slider DrawSizeSlider { get; private set; } + public Button[] PaintTextureButtons { get; private set; } + + public Button UpDownToggle { get; private set; } + public Button ConnectedToggle { get; private set; } public ToolMode ToolMode { get => GetToolMode (); set => SetToolMode (value); } public ToolShape ToolShape { get => GetToolShape(); set => SetToolShape(value); } public int DrawSize { get => GetDrawSize (); set => SetDrawSize (value); } public int Texture { get => GetTexture (); set => SetTexture (value); } + [Export] public Texture2D CornerTextureNormal { get; set; } + [Export] public Texture2D CornerTexturePaint { get; set; } + public override void _Ready() { ToolModeButtons = [ - (ToolMode.Height, GetNode