Compare commits

..

No commits in common. "e72698ffcdca67b9e163c3ae9d786cb37aeee78c" and "82b30d0d70149978bcc6cdde7ee5a728acc5aec3" have entirely different histories.

62 changed files with 277 additions and 1107 deletions

BIN
black.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cj72ibo3c6x8e"
path="res://.godot/imported/black.png-19a8df0b1a4edb74ea2eecb66d46d03d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://black.png"
dest_files=["res://.godot/imported/black.png-19a8df0b1a4edb74ea2eecb66d46d03d.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
editor.scn (Stored with Git LFS)

Binary file not shown.

BIN
editor/brush_hard_circle_mask.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,14 +0,0 @@
[remap]
importer="image"
type="Image"
uid="uid://drok88h02tdre"
path="res://.godot/imported/brush_hard_circle_mask.png-e647df7b970f00cdf2f3f2ac38ad8257.image"
[deps]
source_file="res://editor/brush_hard_circle_mask.png"
dest_files=["res://.godot/imported/brush_hard_circle_mask.png-e647df7b970f00cdf2f3f2ac38ad8257.image"]
[params]

BIN
editor/brush_soft_circle_mask.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,14 +0,0 @@
[remap]
importer="image"
type="Image"
uid="uid://bbdh4btpg08do"
path="res://.godot/imported/brush_soft_circle_mask.png-5af527bedd556c2d7ed38b029e34527e.image"
[deps]
source_file="res://editor/brush_soft_circle_mask.png"
dest_files=["res://.godot/imported/brush_soft_circle_mask.png-5af527bedd556c2d7ed38b029e34527e.image"]
[params]

BIN
editor/edit_mode_button_group.res (Stored with Git LFS)

Binary file not shown.

BIN
editor/menus_theme.res (Stored with Git LFS)

Binary file not shown.

BIN
editor_theme.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -72,7 +72,6 @@ var movement_smoothing := 0.5
##
## Whether or not player movement input processed by the controller should be ignored.
##
@export
var frozen := false
func _input(event: InputEvent) -> void:

View File

@ -9,16 +9,6 @@
config_version=5
_global_script_classes=[{
"base": "TerrainInstance3D",
"class": &"DynamicTerrainInstance3D",
"language": &"GDScript",
"path": "res://terrain/dynamic_terrain_instance_3d.gd"
}, {
"base": "HFlowContainer",
"class": &"ItemSelection",
"language": &"GDScript",
"path": "res://user_interface/button_selection.gd"
}, {
"base": "Node3D",
"class": &"PlayerController",
"language": &"GDScript",
@ -32,27 +22,18 @@ _global_script_classes=[{
"base": "GeometryInstance3D",
"class": &"TerrainInstance3D",
"language": &"GDScript",
"path": "res://terrain/terrain_instance_3d.gd"
}, {
"base": "Resource",
"class": &"TerrainPaint",
"language": &"GDScript",
"path": "res://terrain/paints/terrain_paint.gd"
"path": "res://terrain_instance_3d.gd"
}]
_global_script_class_icons={
"DynamicTerrainInstance3D": "",
"ItemSelection": "",
"PlayerController": "",
"Settings": "",
"TerrainInstance3D": "",
"TerrainPaint": ""
"TerrainInstance3D": ""
}
[application]
config/name="Protectorate"
run/main_scene="res://editor.scn"
config/use_custom_user_dir=true
config/features=PackedStringArray("4.0", "Forward Plus")
config/icon="res://icon.png"

View File

@ -3,8 +3,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bgpk15qrqxly8"
path.s3tc="res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.s3tc.ctex"
path.etc2="res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.etc2.ctex"
path.s3tc="res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.s3tc.ctex"
path.etc2="res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.etc2.ctex"
metadata={
"imported_formats": ["s3tc", "etc2"],
"vram_texture": true
@ -12,8 +12,8 @@ metadata={
[deps]
source_file="res://terrain/paints/default_albedo.png"
dest_files=["res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.s3tc.ctex", "res://.godot/imported/default_albedo.png-ec7b9bee606a4c8482c5f21d50eaafb2.etc2.ctex"]
source_file="res://prototype_tiles_large_albedo.png"
dest_files=["res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.s3tc.ctex", "res://.godot/imported/prototype_tiles_large_albedo.png-c3984e5db888f4b509766546fda5695b.etc2.ctex"]
[params]

View File

@ -1,126 +0,0 @@
class_name DynamicTerrainInstance3D extends TerrainInstance3D
##
## Blank sample value.
##
const BLANK := Color(0.0, 0.0, 0.0, 0.0)
var _editable_image: Image
var _editable_texture: ImageTexture
func _get_brush_area(point: Vector2i, mask_size: Vector2i, mask_scale: float) -> Rect2i:
# Convert worldspace point to image-space coordinates for mask.
var scaled_mask_size := Vector2i(mask_size * mask_scale)
return Rect2i((point + Vector2i(get_size() * 0.5)) - Vector2i(scaled_mask_size * 0.5), scaled_mask_size)
func _init() -> void:
super._init()
_editable_image = Image.create(1, 1, false, Image.FORMAT_RGBAF)
_editable_texture = ImageTexture.create_from_image(_editable_image)
super.resize(Vector2i.ONE)
##
## Clears the terrain map to the value of [code]clear_elevation[/code].
##
func clear(clear_elevation: float) -> void:
_editable_image.fill(Color(0.0, 0.0, 0.0, clampf(clear_elevation, 0.0, 1.0)))
_editable_texture.update(_editable_image)
##
## Oscillates the height of terrain toward a value of [member height_scale] (multiplied by
## [code]level[/code]) around the area of [code]point[/code] determined by [code]mask[/code]
## multiplied by [code]mask_scale[/code] at a rate of [code]intensity[/code].
##
func oscillate(point: Vector2i, level: float, mask: Image, mask_scale: float, intensity: float) -> void:
var mask_size := mask.get_size()
var brush_source := _get_brush_area(point, mask_size, mask_scale)
if brush_source.has_area():
var brush_target := Rect2i(Vector2i.ZERO, get_size()).intersection(brush_source)
if brush_target.has_area():
var mask_ratio := mask_size / brush_source.size
var offset := brush_target.position - brush_source.position
for y in brush_target.size.y:
var mask_y := int((offset.y + y) * mask_ratio.y)
for x in brush_target.size.x:
var coord := brush_target.position + Vector2i(x, y)
var pixel := _editable_image.get_pixelv(coord)
_editable_image.set_pixelv(coord, Color(pixel.r, pixel.g, pixel.b,
lerpf(pixel.a, level, intensity *\
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a)).clamp())
_editable_texture.update(_editable_image)
##
## Paints the texture of the terrain toward a value of [code]color[/code] multiplied by
## [code]intensity[/code] around the area of [code]point[/code] determined by [code]mask[/code]
## multiplied by [code]mask_scale[/code] at a rate of [code]intensity[/code].
##
func paint(point: Vector2i, color: Color, mask: Image, mask_scale: float, intensity: float) -> void:
var mask_size := mask.get_size()
var brush_source := _get_brush_area(point, mask_size, mask_scale)
if brush_source.has_area():
var brush_target := Rect2i(Vector2i.ZERO, get_size()).intersection(brush_source)
if brush_target.has_area():
var mask_ratio := mask_size / brush_source.size
var offset := brush_target.position - brush_source.position
for y in brush_target.size.y:
var mask_y := int((offset.y + y) * mask_ratio.y)
for x in brush_target.size.x:
var coord := brush_target.position + Vector2i(x, y)
var pixel := _editable_image.get_pixelv(coord)
var mask_intensity_delta := intensity *\
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a
_editable_image.set_pixelv(coord, Color(
lerpf(pixel.r, color.r, mask_intensity_delta),
lerpf(pixel.g, color.g, mask_intensity_delta),
lerpf(pixel.b, color.b, mask_intensity_delta), pixel.a).clamp())
_editable_texture.update(_editable_image)
##
## Attempts to resize the terrain geometry and map to be equal to [code]size[/code] (in-engine
## units), with [code]Vector2i.ONE[/code] as the minimum size.
##
## In the process of growing the terrain map, existing edge data will be copied to fill it out.
##
func resize(size: Vector2i) -> void:
super.resize(size)
var actual_size := get_size()
_editable_image.resize(actual_size.x, actual_size.y)
_editable_texture = ImageTexture.create_from_image(_editable_image)
update_terrain(_editable_texture)
##
## Samples the color value in the editable terrain at the worldspace [code]point[/code], returning
## its respective [Color] value.
##
## For sample coordinates outside of the terrain map worldspace, [code]BLANK[/code] is returned
## instead.
##
func sample(point: Vector2i) -> Color:
var size := get_size()
var image_point := point + Vector2i(size * 0.5)
if Rect2i(Vector2i.ZERO, size).has_point(image_point):
return _editable_image.get_pixelv(image_point)
return BLANK

BIN
terrain/paints/arid_grass_albedo.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://jcmf7j3qo6ea"
path="res://.godot/imported/arid_grass_albedo.png-532bc188063dc524e2c08228bed13fa7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/arid_grass_albedo.png"
dest_files=["res://.godot/imported/arid_grass_albedo.png-532bc188063dc524e2c08228bed13fa7.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/arid_grass_displacement.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://co0jompch208v"
path="res://.godot/imported/arid_grass_displacement.png-cad938b62195c0b0f41099d596594b8b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/arid_grass_displacement.png"
dest_files=["res://.godot/imported/arid_grass_displacement.png-cad938b62195c0b0f41099d596594b8b.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/arid_grass_normal.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bh141jkgbmya8"
path="res://.godot/imported/arid_grass_normal.png-7bf9fdf5f927fea47a2f86a9ffab326e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/arid_grass_normal.png"
dest_files=["res://.godot/imported/arid_grass_normal.png-7bf9fdf5f927fea47a2f86a9ffab326e.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/arid_grass_roughness.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://jdq8kwjo3uap"
path="res://.godot/imported/arid_grass_roughness.png-40299cbb0e24b392d013d45af79f5444.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/arid_grass_roughness.png"
dest_files=["res://.godot/imported/arid_grass_roughness.png-40299cbb0e24b392d013d45af79f5444.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

BIN
terrain/paints/cobblestone_albedo.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cs06oiwrord6t"
path="res://.godot/imported/cobblestone_albedo.png-f0ce6b9d25b0c6c4130e70ff660bcbd6.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/cobblestone_albedo.png"
dest_files=["res://.godot/imported/cobblestone_albedo.png-f0ce6b9d25b0c6c4130e70ff660bcbd6.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://mkxbjfwdwkaq"
path="res://.godot/imported/cobblestone_displacement.png-bcf2e2194862b85cb002d9559d57903b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/cobblestone_displacement.png"
dest_files=["res://.godot/imported/cobblestone_displacement.png-bcf2e2194862b85cb002d9559d57903b.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/cobblestone_normal.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ukk0161x3eg2"
path="res://.godot/imported/cobblestone_normal.png-5130e667fa81f7452d15808908f4cb99.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/cobblestone_normal.png"
dest_files=["res://.godot/imported/cobblestone_normal.png-5130e667fa81f7452d15808908f4cb99.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/cobblestone_roughness.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bcybapft8tl2x"
path="res://.godot/imported/cobblestone_roughness.png-2f09da1d7000b898b80d7b177062e509.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/cobblestone_roughness.png"
dest_files=["res://.godot/imported/cobblestone_roughness.png-2f09da1d7000b898b80d7b177062e509.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

BIN
terrain/paints/default_terrain_paint.res (Stored with Git LFS)

Binary file not shown.

BIN
terrain/paints/desert_sand_albedo.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b8cv4q43fsglu"
path="res://.godot/imported/desert_sand_albedo.png-1f8394c37b6df0b83ddc4964049fe1fb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/desert_sand_albedo.png"
dest_files=["res://.godot/imported/desert_sand_albedo.png-1f8394c37b6df0b83ddc4964049fe1fb.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bdacir1igfinb"
path="res://.godot/imported/desert_sand_displacement.png-de6822961a581feed0d45f5f34fbb048.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/desert_sand_displacement.png"
dest_files=["res://.godot/imported/desert_sand_displacement.png-de6822961a581feed0d45f5f34fbb048.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/desert_sand_normal.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c40cc5b5sq4yu"
path="res://.godot/imported/desert_sand_normal.png-4882d77c1942a502a8d07cd8761a392c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/desert_sand_normal.png"
dest_files=["res://.godot/imported/desert_sand_normal.png-4882d77c1942a502a8d07cd8761a392c.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/desert_sand_roughness.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bwkcsnjetn5wr"
path="res://.godot/imported/desert_sand_roughness.png-0c32daf878e9b29d36631441877f21ac.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/desert_sand_roughness.png"
dest_files=["res://.godot/imported/desert_sand_roughness.png-0c32daf878e9b29d36631441877f21ac.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

BIN
terrain/paints/dry_mud_albedo.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://eqbk8dx3px02"
path="res://.godot/imported/dry_mud_albedo.png-6844f23cea910070ff2cf0d2e02e4e06.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/dry_mud_albedo.png"
dest_files=["res://.godot/imported/dry_mud_albedo.png-6844f23cea910070ff2cf0d2e02e4e06.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/dry_mud_displacement.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bwqtubithbfsy"
path="res://.godot/imported/dry_mud_displacement.png-84ac0ae4e00848577ccfe89d2c4787e8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/dry_mud_displacement.png"
dest_files=["res://.godot/imported/dry_mud_displacement.png-84ac0ae4e00848577ccfe89d2c4787e8.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/dry_mud_normal.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c86r5niid1hp1"
path="res://.godot/imported/dry_mud_normal.png-6211d1992b291d2e0174ec9de201218d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/dry_mud_normal.png"
dest_files=["res://.godot/imported/dry_mud_normal.png-6211d1992b291d2e0174ec9de201218d.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/dry_mud_roughness.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://7xnkstxa6q65"
path="res://.godot/imported/dry_mud_roughness.png-35dfe15111e09484a06efd2f6e55b73b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://terrain/paints/dry_mud_roughness.png"
dest_files=["res://.godot/imported/dry_mud_roughness.png-35dfe15111e09484a06efd2f6e55b73b.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

BIN
terrain/paints/dry_mud_terrain_paint.res (Stored with Git LFS)

Binary file not shown.

View File

@ -1,13 +0,0 @@
class_name TerrainPaint extends Resource
##
## Terrain albedo map data.
##
@export
var albedo_map: Texture2D = null
##
## Terrain normal map data.
##
@export
var normal_map: Texture2D = null

View File

@ -1,57 +0,0 @@
shader_type spatial;
const int MAP_COUNT = 4;
uniform sampler2D[MAP_COUNT] ALBEDO_MAPS;
uniform float MAX_HEIGHT = 100.0;
uniform sampler2D[MAP_COUNT] NORMAL_MAPS;
uniform vec2 SIZE;
uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable;
void fragment() {
vec2 uv = UV * (SIZE / 2.0);
vec2 uv_alt = uv * -0.5;
vec3 splat_map = texture(TERRAIN_MAP, UV).rgb;
float blank = clamp(1.0 - splat_map.r - splat_map.g - splat_map.b, 0.0, 1.0);
ALBEDO = blank * 0.5 * (texture(ALBEDO_MAPS[0], uv).rgb + texture(ALBEDO_MAPS[0], uv_alt).rgb);
for (int i = 0; i < (MAP_COUNT - 1); i += 1) {
int map_index = i + 1;
ALBEDO += splat_map[i] * 0.5 * (texture(ALBEDO_MAPS[map_index], uv).rgb +
texture(ALBEDO_MAPS[map_index], uv_alt).rgb);
}
NORMAL_MAP = blank * 0.5 *
(texture(NORMAL_MAPS[0], uv).rgb + texture(NORMAL_MAPS[0], uv_alt).rgb);
for (int i = 0; i < (MAP_COUNT - 1); i += 1) {
int map_index = i + 1;
NORMAL_MAP += splat_map[i] * 0.5 * (texture(NORMAL_MAPS[map_index], uv).rgb +
texture(NORMAL_MAPS[map_index], uv_alt).rgb);
}
}
float height(vec2 uv) {
return MAX_HEIGHT * texture(TERRAIN_MAP, uv).a;
}
void vertex() {
VERTEX.y = height(UV);
vec2 texel_size = UV / SIZE;
vec4 h = vec4(
height(UV + (texel_size * vec2(0, -1))),
height(UV + (texel_size * vec2(-1, 0))),
height(UV + (texel_size * vec2( 1, 0))),
height(UV + (texel_size * vec2( 0, 1))));
NORMAL = normalize(vec3(h.y - h.z, 2.0, h.x - h.w));
}

View File

@ -1,87 +0,0 @@
class_name TerrainInstance3D extends GeometryInstance3D
##
## Identifier constant for a paint slot channel.
##
enum PaintSlot {
ERASE,
RED,
GREEN,
BLUE,
}
const _DETAIL := 2
var _albedo_map_textures: Array[Texture2D] = [null, null, null, null]
var _material := ShaderMaterial.new()
var _normal_map_textures: Array[Texture2D] = [null, null, null, null]
var _mesh := PlaneMesh.new()
##
## The height scale range that is used to determine the minimums and maximums of the terrain map.
##
@export
var height_scale := 100.0:
get:
return height_scale
set(value):
_material.set_shader_parameter("MAX_HEIGHT", value)
height_scale = max(value, 0.0)
var _size := Vector2i.ZERO
func _init() -> void:
_material.shader = preload("res://terrain/terrain.gdshader")
RenderingServer.instance_set_base(get_instance(), _mesh)
_mesh.surface_set_material(0, _material)
##
## Returns the size of the terrain mesh (as in-engine units).
##
func get_size() -> Vector2i:
return _size
##
## Attempts to resize the terrain to be equal to [code]size[/code] (in-engine units), with
## [code]Vector2i.ONE[/code] as the minimum size.
##
func resize(size: Vector2i) -> void:
var width := maxi(size.x, 1)
var height := maxi(size.y, 1)
if (width != _size.x) or (height != _size.y):
_mesh.subdivide_width = width * _DETAIL
_mesh.subdivide_depth = height * _DETAIL
_mesh.size = size
_material.set_shader_parameter("SIZE", Vector2(size))
_size = size
##
## Updates the paint used by the paint channel identified by [code]paint_slot[/code] to
## [code]terrain_paint[/code].
##
func update_paint(paint_slot: PaintSlot, paint: TerrainPaint) -> void:
if paint == null:
_albedo_map_textures[paint_slot] = null
_normal_map_textures[paint_slot] = null
else:
_albedo_map_textures[paint_slot] = paint.albedo_map
_normal_map_textures[paint_slot] = paint.normal_map
_material.set_shader_parameter("ALBEDO_MAPS", _albedo_map_textures)
_material.set_shader_parameter("NORMAL_MAPS", _normal_map_textures)
##
## Updates the terrain map to [code]terrain_map[/code].
##
func update_terrain(terrain_map: Texture2D) -> void:
_material.set_shader_parameter("TERRAIN_MAP", terrain_map)

BIN
terrain_cursor_emission.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,36 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dmbae0p1ujwcv"
path.s3tc="res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.s3tc.ctex"
path.etc2="res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.etc2.ctex"
metadata={
"imported_formats": ["s3tc", "etc2"],
"vram_texture": true
}
[deps]
source_file="res://terrain_cursor_emission.png"
dest_files=["res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.s3tc.ctex", "res://.godot/imported/terrain_cursor_emission.png-242c595842e9c0210b5a4ae1147e42e6.etc2.ctex"]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

169
terrain_instance_3d.gd Normal file
View File

@ -0,0 +1,169 @@
@tool
class_name TerrainInstance3D extends GeometryInstance3D
const _DETAIL := 2
var _mesh := PlaneMesh.new()
var _material := ShaderMaterial.new()
##
##
##
@export
var size: Vector2i = Vector2i.ZERO:
get:
return size
set(value):
var width := maxi(value.x, 0)
var height := maxi(value.y, 0)
if (width != size.x) or (height != size.y):
if (width == 0) and (height == 0):
RenderingServer.instance_set_base(self.get_instance(), RID())
else:
self._mesh.subdivide_width = width * _DETAIL
self._mesh.subdivide_depth = height * _DETAIL
self._mesh.size = value
self._material.set_shader_parameter("SIZE", Vector2(value))
RenderingServer.instance_set_base(self.get_instance(), self._mesh)
size = value
##
##
##
@export
var layer_1_albedo: Texture2D = null:
get:
return layer_1_albedo
set(value):
self._material.set_shader_parameter("LAYER_1_ALBEDO", value)
layer_1_albedo = value
##
##
##
@export
var layer_1_normal_map: Texture2D = null:
get:
return layer_1_normal_map
set(value):
self._material.set_shader_parameter("LAYER_1_NORMAL_MAP", value)
layer_1_normal_map = value
##
##
##
@export
var layer_2_albedo: Texture2D = null:
get:
return layer_2_albedo
set(value):
self._material.set_shader_parameter("LAYER_2_ALBEDO", value)
layer_2_albedo = value
##
##
##
@export
var layer_2_normal_map: Texture2D = null:
get:
return layer_2_normal_map
set(value):
self._material.set_shader_parameter("LAYER_2_NORMAL_MAP", value)
layer_2_normal_map = value
##
##
##
@export
var layer_3_albedo: Texture2D = null:
get:
return layer_3_albedo
set(value):
self._material.set_shader_parameter("LAYER_3_ALBEDO", value)
layer_3_albedo = value
##
##
##
@export
var layer_3_normal_map: Texture2D = null:
get:
return layer_3_normal_map
set(value):
self._material.set_shader_parameter("LAYER_3_NORMAL_MAP", value)
layer_3_normal_map = value
##
##
##
@export
var layer_4_albedo: Texture2D = null:
get:
return layer_4_albedo
set(value):
self._material.set_shader_parameter("LAYER_4_ALBEDO", value)
layer_4_albedo = value
##
##
##
@export
var layer_4_normal_map: Texture2D = null:
get:
return layer_4_normal_map
set(value):
self._material.set_shader_parameter("LAYER_4_NORMAL_MAP", value)
layer_4_normal_map = value
##
##
##
@export
var terrain_map: Texture2D = null:
get:
return terrain_map
set(value):
self._material.set_shader_parameter("TERRAIN_MAP", value)
terrain_map = value
##
##
##
@export
var max_height := 100.0:
get:
return max_height
set(value):
self._material.set_shader_parameter("MAX_HEIGHT", value)
max_height = max(value, 0.0)
func _init() -> void:
self._material.shader = preload("res://terrain_shader.gdshader")
self._mesh.surface_set_material(0, self._material)

58
terrain_shader.gdshader Normal file
View File

@ -0,0 +1,58 @@
shader_type spatial;
uniform sampler2D LAYER_1_ALBEDO : hint_default_black;
uniform sampler2D LAYER_1_NORMAL_MAP : hint_default_black;
uniform sampler2D LAYER_2_ALBEDO : hint_default_black;
uniform sampler2D LAYER_2_NORMAL_MAP : hint_default_black;
uniform sampler2D LAYER_3_ALBEDO : hint_default_black;
uniform sampler2D LAYER_3_NORMAL_MAP : hint_default_black;
uniform sampler2D LAYER_4_ALBEDO : hint_default_black;
uniform sampler2D LAYER_4_NORMAL_MAP : hint_default_black;
uniform float MAX_HEIGHT = 100.0;
uniform vec2 SIZE;
uniform sampler2D TERRAIN_MAP : hint_default_transparent, repeat_disable;
void fragment() {
vec2 uv = UV * SIZE;
vec2 uv_alt = uv * -0.25;
vec3 splat_map = texture(TERRAIN_MAP, UV).rgb;
float blank = clamp(1.0 - splat_map.r - splat_map.g - splat_map.b, 0.0, 1.0);
ALBEDO = blank * 0.5 * (texture(LAYER_1_ALBEDO, uv).rgb + texture(LAYER_1_ALBEDO, uv_alt).rgb);
ALBEDO += splat_map.r * 0.5 * (texture(LAYER_2_ALBEDO, uv).rgb + texture(LAYER_2_ALBEDO, uv_alt).rgb);
ALBEDO += splat_map.g * 0.5 * (texture(LAYER_3_ALBEDO, uv).rgb + texture(LAYER_3_ALBEDO, uv_alt).rgb);
ALBEDO += splat_map.b * 0.5 * (texture(LAYER_4_ALBEDO, uv).rgb + texture(LAYER_4_ALBEDO, uv_alt).rgb);
NORMAL_MAP = blank * 0.5 * (texture(LAYER_1_NORMAL_MAP, uv).rgb + texture(LAYER_1_NORMAL_MAP, uv_alt).rgb);
NORMAL_MAP += splat_map.r * 0.5 * (texture(LAYER_1_NORMAL_MAP, uv).rgb + texture(LAYER_2_NORMAL_MAP, uv_alt).rgb);
NORMAL_MAP += splat_map.g * 0.5 * (texture(LAYER_2_NORMAL_MAP, uv).rgb + texture(LAYER_3_NORMAL_MAP, uv_alt).rgb);
NORMAL_MAP += splat_map.b * 0.5 * (texture(LAYER_3_NORMAL_MAP, uv).rgb + texture(LAYER_4_NORMAL_MAP, uv_alt).rgb);
}
float height(vec2 uv) {
return MAX_HEIGHT * texture(TERRAIN_MAP, uv).a;
}
void vertex() {
VERTEX.y = height(UV);
vec2 texel_size = UV / SIZE;
vec4 h = vec4(
height(UV + (texel_size * vec2(0, -1))),
height(UV + (texel_size * vec2(-1, 0))),
height(UV + (texel_size * vec2( 1, 0))),
height(UV + (texel_size * vec2( 0, 1))));
NORMAL = normalize(vec3(h.y - h.z, 2.0, h.x - h.w));
}

View File

@ -1,75 +0,0 @@
@tool
class_name ItemSelection extends HFlowContainer
##
## An item has been selected via GUI selection or [method select_item].
##
signal item_selected(index: int)
var _button_group := ButtonGroup.new()
##
## Number of items in the selection.
##
var item_count: int:
get:
return _button_group.get_buttons().size()
func _get_configuration_warnings() -> PackedStringArray:
return PackedStringArray()
##
## Adds a new item with no text and only [code]icon[/code] as the icon to the selection.
##
func add_icon_item(icon: Texture2D) -> void:
var child_count := get_child_count()
var button := Button.new()
button.icon = icon
button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
button.toggle_mode = true
button.button_group = _button_group
button.button_pressed = child_count == 0
button.pressed.connect(func () -> void: select_item(child_count))
add_child(button)
##
## Returns the icon used by the item at [code]index[/code].
##
## An assertion is raised if [code]index[/code] is out of bounds from the item count.
##
func get_item_icon(index: int) -> Texture2D:
var buttons := _button_group.get_buttons()
assert(index < buttons.size(), "index out of range")
var button := buttons[index] as Button
return null if (button == null) else button.icon
##
## Returns the currently selected item index or [code]-1[/code] if no item is selected.
##
func get_selected_item() -> int:
var pressed_button := _button_group.get_pressed_button()
return -1 if (pressed_button == null) else pressed_button.get_index()
##
## Selects the item at [code]index[/code], emitting [signal item_selected] at the end.
##
## An assertion is raised if [code]index[/code] is out of bounds from the item count.
##
func select_item(index: int) -> void:
var buttons := _button_group.get_buttons()
assert(index < buttons.size(), "index out of range")
var pressed_button := _button_group.get_pressed_button()
if pressed_button != null:
pressed_button.set_pressed_no_signal(false)
buttons[index].set_pressed_no_signal(true)
item_selected.emit(index)

BIN
user_interface/screen_cursor.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://crt8tmxbpu1hl"
path="res://.godot/imported/screen_cursor.png-46ebd33cd7dfb4c0211a698e6d39e483.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://user_interface/screen_cursor.png"
dest_files=["res://.godot/imported/screen_cursor.png-46ebd33cd7dfb4c0211a698e6d39e483.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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