upgrade terrain_3d

This commit is contained in:
anyreso 2026-02-20 18:49:48 -05:00
parent 721d3f0716
commit dba1bd1b6b
15 changed files with 20 additions and 20 deletions

View file

@ -19,10 +19,10 @@ var _ignore_transform_change: bool = false
func _enter_tree() -> void:
if not Engine.is_editor_hint():
return
for child in get_children():
_on_child_entered_tree(child)
child_entered_tree.connect(_on_child_entered_tree)
child_exiting_tree.connect(_on_child_exiting_tree)
@ -30,10 +30,10 @@ func _enter_tree() -> void:
func _exit_tree() -> void:
if not Engine.is_editor_hint():
return
child_entered_tree.disconnect(_on_child_entered_tree)
child_exiting_tree.disconnect(_on_child_exiting_tree)
for child in get_children():
_on_child_exiting_tree(child)
@ -49,10 +49,10 @@ func get_terrain() -> Terrain3D:
if terrains.size() > 0:
terrain = terrains[0]
_terrain_id = terrain.get_instance_id() if terrain else 0
if terrain and terrain.data and not terrain.data.maps_edited.is_connected(_on_maps_edited):
terrain.data.maps_edited.connect(_on_maps_edited)
return terrain
@ -69,16 +69,16 @@ func _get_terrain_height(p_global_position: Vector3) -> float:
func _on_child_entered_tree(p_node: Node) -> void:
if not (p_node is Node3D):
return
assert(p_node.get_parent() == self)
var helper: TransformChangedNotifier = p_node.get_node_or_null(CHILD_HELPER_PATH)
if not helper:
helper = TransformChangedNotifier.new()
helper.name = CHILD_HELPER_NAME
p_node.add_child(helper, true, INTERNAL_MODE_BACK)
assert(p_node.has_node(CHILD_HELPER_PATH))
# When reparenting a Node3D, Godot changes its transform _after_ reparenting it. So here,
# we must use call_deferred, to avoid receiving transform_changed as a result of reparenting.
_setup_child_signal.call_deferred(p_node, helper)
@ -89,7 +89,7 @@ func _setup_child_signal(p_node: Node, helper: TransformChangedNotifier) -> void
return
if helper.transform_changed.is_connected(_on_child_transform_changed):
return
helper.transform_changed.connect(_on_child_transform_changed.bind(p_node))
_update_child_offset(p_node)
@ -97,14 +97,14 @@ func _setup_child_signal(p_node: Node, helper: TransformChangedNotifier) -> void
func _on_child_exiting_tree(p_node: Node) -> void:
if not (p_node is Node3D) or not p_node.has_node(CHILD_HELPER_PATH):
return
var helper: TransformChangedNotifier = p_node.get_node_or_null(CHILD_HELPER_PATH)
if helper:
if helper.transform_changed.is_connected(_on_child_transform_changed):
helper.transform_changed.disconnect(_on_child_transform_changed)
p_node.remove_child(helper)
helper.queue_free()
_offsets.erase(p_node.get_instance_id())
@ -116,16 +116,16 @@ func _is_node_selected(p_node: Node) -> bool:
func _on_child_transform_changed(p_node: Node3D) -> void:
if _ignore_transform_change:
return
var lmb_down := Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT)
if lmb_down and (_is_node_selected(p_node) or _is_node_selected(self)):
# The user may be moving the node using gizmos.
# We should wait until they're done before updating otherwise gizmos + this node conflict.
return
if not _offsets.has(p_node.get_instance_id()):
return
var old_offset: Vector3 = _offsets[p_node.get_instance_id()]
var old_h: float = _get_terrain_height(old_offset)
var old_position: Vector3 = old_offset + Vector3(0, old_h, 0)
@ -134,13 +134,13 @@ func _on_child_transform_changed(p_node: Node3D) -> void:
return
var new_h: float = _get_terrain_height(new_position)
var new_offset: Vector3 = new_position - Vector3(0, new_h, 0)
var translate_without_reposition: bool = Input.is_key_pressed(KEY_SHIFT)
var y_changed: bool = not is_equal_approx(old_position.y, p_node.global_position.y)
if not y_changed and not translate_without_reposition:
new_offset.y = old_offset.y
new_position = new_offset + Vector3(0, new_h, 0)
# Make sure that when the user undo's the translation, the offset change gets undone too!
_undo_redo.create_action("Translate", UndoRedo.MERGE_ALL)
_undo_redo.add_do_method(self, &"_set_offset_and_position", p_node.get_instance_id(), new_offset, new_position)
@ -152,7 +152,7 @@ func _set_offset_and_position(p_id: int, p_offset: Vector3, p_position: Vector3)
var node := instance_from_id(p_id) as Node
if not is_instance_valid(node):
return
_ignore_transform_change = true
node.global_position = p_position
_offsets[p_id] = p_offset
@ -171,7 +171,7 @@ func _update_child_offset(p_node: Node3D) -> void:
func _update_child_position(p_node: Node3D) -> void:
if not _offsets.has(p_node.get_instance_id()):
return
var position: Vector3 = global_transform * p_node.position
var h: float = _get_terrain_height(position)
var offset: Vector3 = _offsets[p_node.get_instance_id()]
@ -184,7 +184,7 @@ func _on_maps_edited(p_edited_aabb: AABB) -> void:
var edited_area: AABB = p_edited_aabb.grow(1)
edited_area.position.y = -INF
edited_area.end.y = INF
for child in get_children():
var node := child as Node3D
if node && edited_area.has_point(node.global_position):