Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move cursor decals to shader #538

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions project/addons/terrain_3d/src/tool_settings.gd
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ func _ready() -> void:
"unit":"γ", "range":Vector3(0.1, 2.0, 0.01) })
add_setting({ "name":"jitter", "type":SettingType.SLIDER, "list":advanced_list, "default":50,
"unit":"%", "range":Vector3(0, 100, 1) })
add_setting({ "name":"cross_hair_threshold", "type":SettingType.SLIDER, "list":advanced_list, "default":16.,
"unit":"m", "range":Vector3(0, 200, 1) })


func create_submenu(p_parent: Control, p_button_name: String, p_layout: Layout, p_hover_pop: bool = true) -> Container:
Expand Down
242 changes: 85 additions & 157 deletions project/addons/terrain_3d/src/ui.gd
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,20 @@ var setting_has_changed: bool = false
var visible: bool = false
var picking: int = Terrain3DEditor.TOOL_MAX
var picking_callback: Callable
var decal: Decal
var decal_timer: Timer
var gradient_decals: Array[Decal]
var brush_data: Dictionary
var operation_builder: OperationBuilder
var last_tool: Terrain3DEditor.Tool
var last_operation: Terrain3DEditor.Operation
var last_rmb_time: int = 0 # Set in editor.gd

# Compatibility decals, indices; 0 = main brush, 1 = slope point A, 2 = slope point B
var editor_decal_position: Array[Vector2]
var editor_decal_rotation: Array[float]
var editor_decal_size: Array[float]
var editor_decal_color: Array[Color]
var editor_decal_visible: Array[bool]
# Editor decals, indices; 0 = main brush, 1 = slope point A, 2 = slope point B
var editor_decal_position: Array[Vector2] = [Vector2(), Vector2(), Vector2()]
var editor_decal_rotation: Array[float] = [float(), float(), float()]
var editor_decal_size: Array[float] = [float(), float(), float()]
var editor_decal_color: Array[Color] = [Color(), Color(), Color()]
var editor_decal_visible: Array[bool] = [bool(), bool(), bool()]
var editor_brush_texture_rid: RID = RID()
@onready var editor_ring_texture_rid: RID = ring_texture.get_rid()


func _enter_tree() -> void:
Expand All @@ -78,16 +77,6 @@ func _enter_tree() -> void:
plugin.add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, terrain_menu)

_on_tool_changed(Terrain3DEditor.REGION, Terrain3DEditor.ADD)

decal = Decal.new()
add_child(decal)
decal_timer = Timer.new()
decal_timer.wait_time = .5
decal_timer.one_shot = true
decal_timer.timeout.connect(Callable(func(node):
if node:
get_tree().create_tween().tween_property(node, "albedo_mix", 0.0, 0.15)).bind(decal))
add_child(decal_timer)


func _exit_tree() -> void:
Expand All @@ -96,11 +85,6 @@ func _exit_tree() -> void:
toolbar.queue_free()
tool_settings.queue_free()
terrain_menu.queue_free()
decal.queue_free()
decal_timer.queue_free()
for gradient_decal in gradient_decals:
gradient_decal.queue_free()
gradient_decals.clear()


func set_visible(p_visible: bool, p_menu_only: bool = false) -> void:
Expand Down Expand Up @@ -236,6 +220,7 @@ func _on_tool_changed(p_tool: Terrain3DEditor.Tool, p_operation: Terrain3DEditor
to_show.push_back("show_cursor_while_painting")
to_show.push_back("gamma")
to_show.push_back("jitter")
to_show.push_back("cross_hair_threshold")
tool_settings.show_settings(to_show)

operation_builder = null
Expand All @@ -258,7 +243,6 @@ func _on_setting_changed() -> void:
return
brush_data = tool_settings.get_settings()
brush_data["asset_id"] = plugin.asset_dock.get_current_list().get_selected_id()
update_decal()
plugin.editor.set_brush_data(brush_data)
plugin.editor.set_operation(_modify_operation(plugin.editor.get_operation()))

Expand Down Expand Up @@ -299,6 +283,10 @@ func _invert_operation(p_operation: Terrain3DEditor.Operation, flags: int = OP_N


func update_decal() -> void:
if !plugin.terrain:
return
var mat_rid: RID = plugin.terrain.material.get_material_rid()

# If not a state that should show the decal, hide everything and return
if not visible or \
not plugin.terrain or \
Expand All @@ -309,182 +297,122 @@ func update_decal() -> void:
brush_data.is_empty() or \
plugin.editor.get_tool() == Terrain3DEditor.REGION or \
(plugin._input_mode > 0 and not brush_data["show_cursor_while_painting"]):
decal.visible = false
for gradient_decal in gradient_decals:
gradient_decal.visible = false
editor_decal_visible[0] = false
editor_decal_visible[1] = false
editor_decal_visible[2] = false
RenderingServer.material_set_param(mat_rid, "_editor_decal_visible", editor_decal_visible)
return

decal.position = plugin.mouse_global_position
decal.visible = true
decal.size = Vector3.ONE * maxf(brush_data["size"], .5)
editor_decal_position[0] = Vector2(plugin.mouse_global_position.x, plugin.mouse_global_position.z)
editor_decal_visible[0] = true
editor_decal_size[0] = maxf(brush_data["size"], .5)
if brush_data["align_to_view"]:
var cam: Camera3D = plugin.terrain.get_camera();
if (cam):
decal.rotation.y = cam.rotation.y
editor_decal_rotation[0] = cam.rotation.y
else:
decal.rotation.y = 0

editor_decal_rotation[0] = 0
# Set texture and color
if picking != Terrain3DEditor.TOOL_MAX:
decal.texture_albedo = ring_texture
decal.size = Vector3.ONE * 10. * plugin.terrain.get_vertex_spacing()
editor_brush_texture_rid = ring_texture.get_rid()
editor_decal_size[0] = 10. * plugin.terrain.get_vertex_spacing()
match picking:
Terrain3DEditor.HEIGHT:
decal.modulate = COLOR_PICK_HEIGHT
editor_decal_color[0] = COLOR_PICK_HEIGHT
Terrain3DEditor.COLOR:
decal.modulate = COLOR_PICK_COLOR
editor_decal_color[0] = COLOR_PICK_COLOR
Terrain3DEditor.ROUGHNESS:
decal.modulate = COLOR_PICK_ROUGH
decal.modulate.a = 1.0
editor_decal_color[0] = COLOR_PICK_ROUGH
editor_decal_color[0].a = 1.0
else:
decal.texture_albedo = brush_data["brush"][1]
editor_brush_texture_rid = brush_data["brush"][1].get_rid()
match plugin.editor.get_tool():
Terrain3DEditor.SCULPT:
match plugin.editor.get_operation():
Terrain3DEditor.ADD:
if plugin.modifier_alt:
decal.modulate = COLOR_LIFT
decal.modulate.a = clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = COLOR_LIFT
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5)
else:
decal.modulate = COLOR_RAISE
decal.modulate.a = clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = COLOR_RAISE
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5)
Terrain3DEditor.SUBTRACT:
if plugin.modifier_alt:
decal.modulate = COLOR_FLATTEN
decal.modulate.a = clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = COLOR_FLATTEN
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5)
else:
decal.modulate = COLOR_LOWER
decal.modulate.a = clamp(brush_data["strength"], .2, .5) + .5
editor_decal_color[0] = COLOR_LOWER
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5) + .5
Terrain3DEditor.AVERAGE:
decal.modulate = COLOR_SMOOTH
decal.modulate.a = clamp(brush_data["strength"], .2, .5) + .2
editor_decal_color[0] = COLOR_SMOOTH
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5) + .2
Terrain3DEditor.GRADIENT:
decal.modulate = COLOR_SLOPE
decal.modulate.a = clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = COLOR_SLOPE
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5)
Terrain3DEditor.HEIGHT:
decal.modulate = COLOR_HEIGHT
decal.modulate.a = clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = COLOR_HEIGHT
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5)
Terrain3DEditor.TEXTURE:
match plugin.editor.get_operation():
Terrain3DEditor.REPLACE:
decal.modulate = COLOR_PAINT
decal.modulate.a = .7
editor_decal_color[0] = COLOR_PAINT
editor_decal_color[0].a = .7
Terrain3DEditor.ADD:
decal.modulate = COLOR_SPRAY
decal.modulate.a = clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = COLOR_SPRAY
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5)
Terrain3DEditor.COLOR:
decal.modulate = brush_data["color"].srgb_to_linear()
decal.modulate.a *= clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = brush_data["color"].srgb_to_linear()
editor_decal_color[0].a *= clamp(brush_data["strength"], .2, .5)
Terrain3DEditor.ROUGHNESS:
decal.modulate = COLOR_ROUGHNESS
decal.modulate.a = clamp(brush_data["strength"], .2, .5)
editor_decal_color[0] = COLOR_ROUGHNESS
editor_decal_color[0].a = clamp(brush_data["strength"], .2, .5)
Terrain3DEditor.AUTOSHADER:
decal.modulate = COLOR_AUTOSHADER
decal.modulate.a = .7
editor_decal_color[0] = COLOR_AUTOSHADER
editor_decal_color[0].a = .7
Terrain3DEditor.HOLES:
decal.modulate = COLOR_HOLES
decal.modulate.a = .85
editor_decal_color[0] = COLOR_HOLES
editor_decal_color[0].a = .85
Terrain3DEditor.NAVIGATION:
decal.modulate = COLOR_NAVIGATION
decal.modulate.a = .85
editor_decal_color[0] = COLOR_NAVIGATION
editor_decal_color[0].a = .85
Terrain3DEditor.INSTANCER:
decal.texture_albedo = ring_texture
decal.modulate = COLOR_INSTANCER
decal.modulate.a = 1.0
decal.size.y = max(1000, decal.size.y)
decal.albedo_mix = 1.0
decal.cull_mask = 1 << ( plugin.terrain.get_mouse_layer() - 1 )
decal_timer.start()

for gradient_decal in gradient_decals:
gradient_decal.visible = false
editor_brush_texture_rid = ring_texture.get_rid()
editor_decal_color[0] = COLOR_INSTANCER
editor_decal_color[0].a = 1.0

if plugin.editor.get_operation() == Terrain3DEditor.GRADIENT:
var index := 0
for point in brush_data["gradient_points"]:
if point != Vector3.ZERO:
var point_decal: Decal = _get_gradient_decal(index)
point_decal.visible = true
point_decal.position = point
index += 1

update_compatibility_decal()


func _get_gradient_decal(index: int) -> Decal:
if gradient_decals.size() > index:
return gradient_decals[index]
editor_decal_visible[1] = false
editor_decal_visible[2] = false

var gradient_decal := Decal.new()
gradient_decal = Decal.new()
gradient_decal.texture_albedo = ring_texture
gradient_decal.modulate = COLOR_SLOPE
gradient_decal.size = Vector3.ONE * 10. * plugin.terrain.get_vertex_spacing()
gradient_decal.size.y = 1000.
gradient_decal.cull_mask = decal.cull_mask
add_child(gradient_decal)
if plugin.editor.get_operation() == Terrain3DEditor.GRADIENT:
var point1: Vector3 = brush_data["gradient_points"][0]
if point1 != Vector3.ZERO:
editor_decal_color[1] = COLOR_SLOPE
editor_decal_size[1] = 10. * plugin.terrain.get_vertex_spacing()
editor_decal_visible[1] = true
editor_decal_position[1] = Vector2(point1.x, point1.z)
var point2: Vector3 = brush_data["gradient_points"][1]
if point2 != Vector3.ZERO:
editor_decal_color[2] = COLOR_SLOPE
editor_decal_size[2] = 10. * plugin.terrain.get_vertex_spacing()
editor_decal_visible[2] = true
editor_decal_position[2] = Vector2(point2.x, point2.z)

gradient_decals.push_back(gradient_decal)
return gradient_decal


func update_compatibility_decal() -> void:
if not plugin.terrain.is_compatibility_mode():
return

# Verify setup
if editor_decal_position.size() != 3:
editor_decal_position.resize(3)
editor_decal_rotation.resize(3)
editor_decal_size.resize(3)
editor_decal_color.resize(3)
editor_decal_visible.resize(3)
decal_timer.timeout.connect(func():
var mat_rid: RID = plugin.terrain.material.get_material_rid()
editor_decal_visible[0] = false
RenderingServer.material_set_param(mat_rid, "_editor_decal_visible", editor_decal_visible)
)

# Update compatibility decal
var mat_rid: RID = plugin.terrain.material.get_material_rid()
if decal.visible:
editor_decal_position[0] = Vector2(decal.global_position.x, decal.global_position.z)
editor_decal_rotation[0] = decal.rotation.y
editor_decal_size[0] = brush_data.get("size")
editor_decal_color[0] = decal.modulate
editor_decal_visible[0] = decal.visible
RenderingServer.material_set_param(
mat_rid, "_editor_decal_0", decal.texture_albedo.get_rid()
)
if gradient_decals.size() >= 1:
editor_decal_position[1] = Vector2(gradient_decals[0].global_position.x,
gradient_decals[0].global_position.z)
editor_decal_rotation[1] = gradient_decals[0].rotation.y
editor_decal_size[1] = 10.0
editor_decal_color[1] = gradient_decals[0].modulate
editor_decal_visible[1] = gradient_decals[0].visible
RenderingServer.material_set_param(
mat_rid, "_editor_decal_1", gradient_decals[0].texture_albedo.get_rid()
)
if gradient_decals.size() >= 2:
editor_decal_position[2] = Vector2(gradient_decals[1].global_position.x,
gradient_decals[1].global_position.z)
editor_decal_rotation[2] = gradient_decals[1].rotation.y
editor_decal_size[2] = 10.0
editor_decal_color[2] = gradient_decals[1].modulate
editor_decal_visible[2] = gradient_decals[1].visible
RenderingServer.material_set_param(
mat_rid, "_editor_decal_2", gradient_decals[1].texture_albedo.get_rid()
)
# Update Shader params
RenderingServer.material_set_param(mat_rid, "_editor_brush_texture", editor_brush_texture_rid)
RenderingServer.material_set_param(mat_rid, "_editor_ring_texture", editor_ring_texture_rid)
RenderingServer.material_set_param(mat_rid, "_editor_decal_position", editor_decal_position)
RenderingServer.material_set_param(mat_rid, "_editor_decal_rotation", editor_decal_rotation)
RenderingServer.material_set_param(mat_rid, "_editor_decal_size", editor_decal_size)
RenderingServer.material_set_param(mat_rid, "_editor_decal_color", editor_decal_color)
RenderingServer.material_set_param(mat_rid, "_editor_decal_visible", editor_decal_visible)

RenderingServer.material_set_param(mat_rid, "_editor_decal_timestamp", float(Time.get_ticks_msec()) / 1000.0 + 0.5)
RenderingServer.material_set_param(mat_rid, "_editor_cross_hair_threshold", brush_data["cross_hair_threshold"] + 0.1)

func set_decal_rotation(p_rot: float) -> void:
decal.rotation.y = p_rot
editor_decal_rotation[0] = p_rot
var mat_rid: RID = plugin.terrain.material.get_material_rid()
RenderingServer.material_set_param(mat_rid, "_editor_decal_rotation", editor_decal_rotation)


func _on_picking(p_type: int, p_callback: Callable) -> void:
Expand Down
Loading