Editor Terrain Brush #2
BIN
editor.scn (Stored with Git LFS)
BIN
editor.scn (Stored with Git LFS)
Binary file not shown.
BIN
editor/edit_mode_button_group.res (Stored with Git LFS)
BIN
editor/edit_mode_button_group.res (Stored with Git LFS)
Binary file not shown.
|
@ -14,6 +14,11 @@ _global_script_classes=[{
|
||||||
"language": &"GDScript",
|
"language": &"GDScript",
|
||||||
"path": "res://terrain/dynamic_terrain_instance_3d.gd"
|
"path": "res://terrain/dynamic_terrain_instance_3d.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "HFlowContainer",
|
||||||
|
"class": &"ItemSelection",
|
||||||
|
"language": &"GDScript",
|
||||||
|
"path": "res://user_interface/button_selection.gd"
|
||||||
|
}, {
|
||||||
"base": "Node3D",
|
"base": "Node3D",
|
||||||
"class": &"PlayerController",
|
"class": &"PlayerController",
|
||||||
"language": &"GDScript",
|
"language": &"GDScript",
|
||||||
|
@ -36,6 +41,7 @@ _global_script_classes=[{
|
||||||
}]
|
}]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
"DynamicTerrainInstance3D": "",
|
"DynamicTerrainInstance3D": "",
|
||||||
|
"ItemSelection": "",
|
||||||
"PlayerController": "",
|
"PlayerController": "",
|
||||||
"Settings": "",
|
"Settings": "",
|
||||||
"TerrainInstance3D": "",
|
"TerrainInstance3D": "",
|
||||||
|
|
|
@ -31,11 +31,11 @@ func clear(clear_elevation: float) -> void:
|
||||||
_editable_texture.update(_editable_image)
|
_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].
|
||||||
kayomn marked this conversation as resolved
Outdated
|
|||||||
##
|
##
|
||||||
##
|
func oscillate(point: Vector2i, level: float, mask: Image, mask_scale: float, intensity: float) -> void:
|
||||||
func oscillate(point: Vector2i, level: float,
|
|
||||||
mask: Image, mask_scale: float, intensity: float, delta: float) -> void:
|
|
||||||
|
|
||||||
var mask_size := mask.get_size()
|
var mask_size := mask.get_size()
|
||||||
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
||||||
|
|
||||||
|
@ -54,17 +54,17 @@ func oscillate(point: Vector2i, level: float,
|
||||||
var pixel := _editable_image.get_pixelv(coord)
|
var pixel := _editable_image.get_pixelv(coord)
|
||||||
|
|
||||||
_editable_image.set_pixelv(coord, Color(pixel.r, pixel.g, pixel.b,
|
_editable_image.set_pixelv(coord, Color(pixel.r, pixel.g, pixel.b,
|
||||||
lerpf(pixel.a, level, intensity * delta *\
|
lerpf(pixel.a, level, intensity *\
|
||||||
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a)).clamp())
|
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a)).clamp())
|
||||||
|
|
||||||
_editable_texture.update(_editable_image)
|
_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].
|
||||||
kayomn marked this conversation as resolved
Outdated
kayomn
commented
Missing doc comment. Missing doc comment.
|
|||||||
##
|
##
|
||||||
##
|
func paint(point: Vector2i, color: Color, mask: Image, mask_scale: float, intensity: float) -> void:
|
||||||
func paint(point: Vector2i, color: Color,
|
|
||||||
mask: Image, mask_scale: float, intensity: float, delta: float) -> void:
|
|
||||||
|
|
||||||
var mask_size := mask.get_size()
|
var mask_size := mask.get_size()
|
||||||
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
var brush_source := _get_brush_area(point, mask_size, mask_scale)
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ func paint(point: Vector2i, color: Color,
|
||||||
var coord := brush_target.position + Vector2i(x, y)
|
var coord := brush_target.position + Vector2i(x, y)
|
||||||
var pixel := _editable_image.get_pixelv(coord)
|
var pixel := _editable_image.get_pixelv(coord)
|
||||||
|
|
||||||
var mask_intensity_delta := intensity * delta *\
|
var mask_intensity_delta := intensity *\
|
||||||
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a
|
mask.get_pixel(int((offset.x + x) * mask_ratio.x), mask_y).a
|
||||||
|
|
||||||
_editable_image.set_pixelv(coord, Color(
|
_editable_image.set_pixelv(coord, Color(
|
||||||
|
@ -93,7 +93,10 @@ func paint(point: Vector2i, color: Color,
|
||||||
_editable_texture.update(_editable_image)
|
_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.
|
||||||
##
|
##
|
||||||
kayomn marked this conversation as resolved
kayomn
commented
Missing doc comment. Missing doc comment.
|
|||||||
|
## In the process of growing the terrain map, existing edge data will be copied to fill it out.
|
||||||
##
|
##
|
||||||
func resize(size: Vector2i) -> void:
|
func resize(size: Vector2i) -> void:
|
||||||
super.resize(size)
|
super.resize(size)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
class_name TerrainPaint extends Resource
|
class_name TerrainPaint extends Resource
|
||||||
|
|
||||||
##
|
##
|
||||||
##
|
## Terrain albedo map data.
|
||||||
##
|
##
|
||||||
@export
|
@export
|
||||||
var albedo_map: Texture2D = null
|
var albedo_map: Texture2D = null
|
||||||
kayomn marked this conversation as resolved
kayomn
commented
Missing doc comment. Missing doc comment.
|
|||||||
|
|
||||||
##
|
##
|
||||||
##
|
## Terrain normal map data.
|
||||||
##
|
##
|
||||||
@export
|
@export
|
||||||
var normal_map: Texture2D = null
|
var normal_map: Texture2D = null
|
||||||
kayomn marked this conversation as resolved
kayomn
commented
Missing doc comment. Missing doc comment.
|
|||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
@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)
|
Loading…
Reference in New Issue
Missing doc comment.