mise a jour addons

This commit is contained in:
deed 2024-01-26 21:00:32 +01:00
parent 9a36dd059c
commit c27c38be13
51 changed files with 576 additions and 251 deletions

View file

@ -1,3 +1,3 @@
source_md5="d28fc1b4998adc3f0ef9aeebc3099059"
dest_md5="9d25e863ac55fd1d3e430f85c32712f4"
dest_md5="6ce83fd2912a369d4bda57c992027f33"

View file

@ -221,7 +221,7 @@ static func request_parent_to_rebuild(node: Node, deferred := true) -> void:
# Recursively search for all MeshInstances3D in the node's children and
# returns them all in an array. If node is a MeshInstance, it will also be
# added to the array
static func get_all_mesh_instances_from(node: Node3D) -> Array[MeshInstance3D]:
static func get_all_mesh_instances_from(node: Node) -> Array[MeshInstance3D]:
var res: Array[MeshInstance3D] = []
if node is MeshInstance3D:
@ -427,7 +427,7 @@ static func get_merged_meshes_from(item: ProtonScatterItem) -> MeshInstance3D:
return instance
static func get_all_static_bodies_from(node: Node3D) -> Array[StaticBody3D]:
static func get_all_static_bodies_from(node: Node) -> Array[StaticBody3D]:
var res: Array[StaticBody3D] = []
if node is StaticBody3D:

View file

@ -2,7 +2,7 @@
importer="glsl"
type="RDShaderFile"
uid="uid://p5gs3onqlpf2"
uid="uid://dksrw0kl2yjtg"
path="res://.godot/imported/compute_relax.glsl-b06f9e60cda7719b78bde9673f2501b7.res"
[deps]

View file

@ -153,7 +153,8 @@ func _on_load_full_preset(path: String) -> void:
ProtonScatterUtil.set_owner_recursive(_scatter_node, get_tree().get_edited_scene_root())
preset.queue_free()
_scatter_node.rebuild.call_deferred()
hide()

View file

@ -721,5 +721,10 @@ func _on_transforms_ready(new_transforms: ProtonScatterTransformList) -> void:
update_gizmos()
build_version += 1
if not is_inside_tree():
return
await get_tree().process_frame
build_completed.emit()

View file

@ -4,7 +4,6 @@ extends "base_parameter.gd"
@onready var _label: Label = $%Label
@onready var _select_button: Button = $%SelectButton
@onready var _clear_button: Button = $%ClearButton
@onready var _popup: ConfirmationDialog = $%ConfirmationDialog
@onready var _tree: Tree = $%Tree
@ -48,26 +47,39 @@ func get_value() -> NodePath:
func _populate_tree() -> void:
_tree.clear()
var scene_root: Node = get_tree().get_edited_scene_root()
var editor_theme: Theme
var tmp = EditorPlugin.new() # TODO: check if this works in release builds
var gui: Control = tmp.get_editor_interface().get_base_control()
var editor_theme = gui.get_theme()
tmp.queue_free()
if EditorInterface.has_method("get_editor_theme"):
editor_theme = EditorInterface.get_editor_theme()
else:
# 4.1 backward compatibility
var tmp = EditorPlugin.new() # TODO: check if this works in release builds
var gui: Control = tmp.get_editor_interface().get_base_control()
editor_theme = gui.get_theme()
tmp.queue_free()
_create_items_recursive(scene_root, null, editor_theme)
func _create_items_recursive(node, parent, theme) -> void:
func _create_items_recursive(node: Node, parent: TreeItem, editor_theme: Theme) -> void:
if parent and not node.owner:
return # Hidden node.
var node_item = _tree.create_item(parent)
node_item.set_text(0, node.get_name())
node_item.set_meta("node", node)
node_item.set_icon(0, theme.get_icon(node.get_class(), "EditorIcons"))
var node_icon: Texture2D
var node_class := node.get_class()
if is_instance_valid(editor_theme):
if editor_theme.has_icon(node_class, "EditorIcons"):
node_icon = editor_theme.get_icon(node_class, "EditorIcons")
else:
node_icon = editor_theme.get_icon("Node", "EditorIcons")
node_item.set_icon(0, node_icon)
for child in node.get_children():
_create_items_recursive(child, node_item, theme)
_create_items_recursive(child, node_item, editor_theme)
func _on_select_button_pressed() -> void:

View file

@ -73,6 +73,7 @@ func _validate_stack_connections() -> void:
if _modifier_stack.just_created:
%Presets.load_default(_scatter)
_modifier_stack.just_created = false
rebuild_ui()
func _set_children_owner(new_owner: Node, node: Node):

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends Node3D
@ -62,10 +62,10 @@ func _physics_process(delta: float) -> void:
var altitude = _system.get_water_altitude(global_transform.origin)
if altitude < 0.0:
var flow = _system.get_water_flow(global_transform.origin)
_rb.add_central_force(Vector3.UP * buoyancy_force * -altitude)
_rb.apply_central_force(Vector3.UP * buoyancy_force * -altitude)
var rot = _get_rotation_correction()
_rb.add_torque(rot * up_correcting_force)
_rb.add_central_force(flow * flow_force)
_rb.apply_torque(rot * up_correcting_force)
_rb.apply_central_force(flow * flow_force)
_rb.linear_damp = water_resistance
_rb.angular_damp = water_resistance
else:

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends EditorProperty

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends SubViewport

View file

@ -2,17 +2,18 @@
[ext_resource type="Script" path="res://addons/waterways/filter_renderer.gd" id="1"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_8d4jc"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wr5gn"]
[node name="Renderer" type="SubViewport"]
own_world_3d = true
transparent_bg = true
use_hdr_2d = true
gui_disable_input = true
size = Vector2i(256, 256)
render_target_update_mode = 1
script = ExtResource("1")
[node name="ColorRect" type="ColorRect" parent="."]
material = SubResource("ShaderMaterial_8d4jc")
material = SubResource("ShaderMaterial_wr5gn")
offset_right = 256.0
offset_bottom = 256.0

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends HBoxContainer

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends Window

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends HBoxContainer

View file

@ -1,10 +1,10 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends EditorNode3DGizmoPlugin
const RiverManager = preload("./river_manager.gd")
const RiverControls = preload("./gui/river_controls.gd")
const RiverManager = preload("./../river_manager.gd")
const RiverControls = preload("./river_controls.gd")
const HANDLES_PER_POINT = 5
const AXIS_CONSTRAINT_LENGTH = 4096
const AXIS_MAPPING := {
@ -71,22 +71,18 @@ func _init() -> void:
add_material("handle_lines", mat)
func _get_gizmo_name():
return "Waterways"
func reset() -> void:
_handle_base_transform = null
func get_name() -> String:
func _get_gizmo_name() -> String:
return "RiverInput"
func _has_gizmo(spatial) -> bool:
return spatial is RiverManager
func _has_gizmo(node_3d) -> bool:
return node_3d is RiverManager
# TODO - figure out of this new "secondary" bool should be used
# TODO - figure out how this new "secondary" bool should be used
func _get_handle_name(gizmo: EditorNode3DGizmo, index: int, secondary: bool) -> String:
return "Handle " + str(index)
@ -180,7 +176,7 @@ func _get_handle_value(gizmo: EditorNode3DGizmo, index: int, secondary: bool):
# Called when handle is moved
# TODO - figure out of this new "secondary" bool should be used
# TODO - figure out how this new "secondary" bool should be used
func _set_handle(gizmo: EditorNode3DGizmo, index: int, secondary: bool, camera: Camera3D, point: Vector2) -> void:
var river : RiverManager = gizmo.get_node_3d()
var space_state = river.get_world_3d().direct_space_state
@ -263,8 +259,8 @@ func _set_handle(gizmo: EditorNode3DGizmo, index: int, secondary: bool, camera:
if editor_plugin.local_editing:
normal = _handle_base_transform.basis * (normal)
var projected : Vector3 = old_pos_global.project(normal)
var direction : Vector3 = sign(projected.dot(normal))
var distance : Vector3 = direction * projected.length()
var direction : float = signf(projected.dot(normal))
var distance : float = direction * projected.length()
var plane := Plane(normal, distance)
new_pos = plane.intersects_ray(ray_from, ray_dir)
@ -289,6 +285,7 @@ func _set_handle(gizmo: EditorNode3DGizmo, index: int, secondary: bool, camera:
# Widths handles
if is_width_left or is_width_right:
print("is width left or right")
var p1 = base
var p2
if is_width_left:
@ -302,10 +299,12 @@ func _set_handle(gizmo: EditorNode3DGizmo, index: int, secondary: bool, camera:
var dir = geo_points[0].distance_to(base) - old_pos.distance_to(base)
river.widths[p_index] += dir
# Ensure width handles don't end up inside the center point
river.widths[p_index] = max(river.widths[p_index], MIN_DIST_TO_CENTER_HANDLE)
# ensures that setter get's called so river regenerates - TODO probably find a nicer way of doing this
river.widths = river.widths
_redraw(gizmo)
# Handle Undo / Redo of handle movements
@ -358,12 +357,12 @@ func _redraw(gizmo: EditorNode3DGizmo) -> void:
if not _handle_lines_mat:
_handle_lines_mat = get_material("handle_lines", gizmo)
gizmo.clear()
var river := gizmo.get_node_3d() as RiverManager
if not river.is_connected("river_changed", Callable(self, "_redraw")):
river.river_changed.connect(_redraw.bind(gizmo))
_draw_path(gizmo, river.curve)
_draw_handles(gizmo, river)

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends MenuButton

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends HBoxContainer

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=3 format=3 uid="uid://dub07tcwh54lt"]
[gd_scene load_steps=3 format=3 uid="uid://b7sb78as2wbok"]
[ext_resource type="Script" path="res://addons/waterways/gui/water_system_controls.gd" id="1"]
[ext_resource type="Script" path="res://addons/waterways/gui/water_system_menu.gd" id="2"]

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends MenuButton

View file

@ -0,0 +1,97 @@
extends EditorNode3DGizmoPlugin
const WaterfallManager = preload("./../waterfall_manager.gd")
var editor_plugin : EditorPlugin
func _init() -> void:
create_handle_material("handles")
var handles_mat := get_material("handles")
handles_mat.set_albedo(Color(1.0, 0.0, 0.0, 1.0))
handles_mat.set_flag(StandardMaterial3D.FLAG_DISABLE_DEPTH_TEST, false)
# var mat = StandardMaterial3D.new()
# mat.shading_mode = StandardMaterial3D.SHADING_MODE_UNSHADED
# mat.set_flag(StandardMaterial3D.FLAG_DISABLE_DEPTH_TEST, true)
# mat.set_albedo(Color(1.0, 1.0, 0.0))
# mat.render_priority = 10
# add_material("path", mat)
func _get_gizmo_name() -> String:
return "WaterfallInput"
func _has_gizmo(node_3d: Node3D) -> bool:
return node_3d is WaterfallManager
func _get_handle_name(gizmo: EditorNode3DGizmo, index: int, secondary: bool) -> String:
return "Handle " + str(index)
func _get_handle_value(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool):
var waterfall : WaterfallManager = gizmo.get_node_3d()
if handle_id == 0:
return waterfall.points[0]
if handle_id == 1:
return waterfall.points[1]
func _set_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, camera: Camera3D, screen_pos: Vector2) -> void:
var waterfall : WaterfallManager = gizmo.get_node_3d()
var global_transform : Transform3D = waterfall.transform
if waterfall.is_inside_tree():
global_transform = waterfall.get_global_transform()
var ray_from = camera.project_ray_origin(screen_pos)
var ray_dir = camera.project_ray_normal(screen_pos)
var old_pos : Vector3 = waterfall.get_points()[handle_id]
var old_pos_global : Vector3 = waterfall.to_global(old_pos)
var new_pos : Vector3
var plane = Plane(old_pos_global, old_pos_global + camera.transform.basis.x, old_pos_global + camera.transform.basis.y)
new_pos = plane.intersects_ray(ray_from, ray_dir)
var new_pos_local = waterfall.to_local(new_pos)
waterfall.set_point(handle_id, new_pos_local)
_redraw(gizmo)
func _commit_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, restore, cancel: bool) -> void:
var waterfall : WaterfallManager = gizmo.get_node_3d()
var ur := editor_plugin.get_undo_redo()
ur.create_action("Change Waterfall Shape")
if handle_id == 0:
ur.add_do_method(waterfall, "set_point", 0, waterfall.points[0])
ur.add_undo_method(waterfall, "set_point", 0, restore)
if handle_id == 1:
ur.add_do_method(waterfall, "set_point", 1, waterfall.points[1])
ur.add_undo_method(waterfall, "set_point", 1, restore)
ur.add_do_method(waterfall, "properties_changed")
ur.add_undo_method(waterfall, "properties_changed")
ur.commit_action()
func _redraw(gizmo: EditorNode3DGizmo) -> void:
gizmo.clear()
var waterfall := gizmo.get_node_3d() as WaterfallManager
var handles := PackedVector3Array()
handles.append(waterfall.points[0])
handles.append(waterfall.points[1])
gizmo.add_handles(handles, get_material("handles", gizmo), [])
if not waterfall.is_connected("waterfall_changed", Callable(self, "_redraw")):
waterfall.waterfall_changed.connect(_redraw.bind(gizmo))

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/buoyant.svg-ac69eb28a931579c132428200cb0835d.
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/create.svg-60b9f1716ebcb842a99e86316911f9a2.c
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/delete.svg-1b0c65778cb549f4dbd4d033751da946.c
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/river.svg-233e9c2c3b3e593909a8b0720e3d3ed5.ct
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/select.svg-76eee65280a05a4a0c6a5b26562361ea.c
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/system.svg-c22af9c26d0684bdbe9cafe3e334da94.c
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends EditorInspectorPlugin
@ -10,7 +10,7 @@ func _can_handle(object) -> bool:
return object is RiverManager
func _parse_property(object: Object, type: Variant.Type, name: String, hint: PropertyHint, hint_text: String, usage: int, wide: bool) -> bool:
func _parse_property(object: Object, type: Variant.Type, name: String, hint_type: PropertyHint, hint_string: String, usage_flags, wide: bool) -> bool:
if type == TYPE_PROJECTION and "color" in name:
var editor_property = _editor.new()
add_property_editor(name, editor_property)

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends EditorPlugin
@ -6,12 +6,16 @@ extends EditorPlugin
const WaterHelperMethods = preload("./water_helper_methods.gd")
const WaterSystem = preload("./water_system_manager.gd")
const RiverManager = preload("./river_manager.gd")
const RiverGizmo = preload("./river_gizmo.gd")
const WaterfallManager = preload("./waterfall_manager.gd")
const WaterfallConfiguration = preload("./waterfall_configuration.gd")
const RiverGizmo = preload("./gui/river_gizmo.gd")
const WaterfallGizmo = preload("./gui/waterfall_gizmo.gd")
const InspectorPlugin = preload("./inspector_plugin.gd")
const ProgressWindow = preload("./gui/progress_window.tscn")
const RiverControls = preload("./gui/river_controls.gd")
var river_gizmo: RiverGizmo = RiverGizmo.new()
var waterfall_gizmo: WaterfallGizmo = WaterfallGizmo.new()
var gradient_inspector: InspectorPlugin = InspectorPlugin.new()
var _river_controls = preload("./gui/river_controls.tscn").instantiate()
@ -26,12 +30,16 @@ var local_editing := false
func _enter_tree() -> void:
add_custom_type("River", "Node3D", preload("./river_manager.gd"), preload("./icons/river.svg"))
add_custom_type("River", "Node3D",RiverManager, preload("./icons/river.svg"))
add_custom_type("Waterfall", "Node3D", WaterfallManager, preload("./icons/river.svg"))
add_custom_type("WaterfallConfiguration", "Resource", WaterfallConfiguration, preload("./icons/river.svg"))
add_custom_type("WaterSystem", "Node3D", preload("./water_system_manager.gd"), preload("./icons/system.svg"))
add_custom_type("Buoyant", "Node3D", preload("./buoyant_manager.gd"), preload("./icons/buoyant.svg"))
add_node_3d_gizmo_plugin(river_gizmo)
add_node_3d_gizmo_plugin(waterfall_gizmo)
add_inspector_plugin(gradient_inspector)
river_gizmo.editor_plugin = self
waterfall_gizmo.editor_plugin = self
_river_controls.connect("mode", Callable(self, "_on_mode_change"))
_river_controls.connect("options", Callable(self, "_on_option_change"))
_progress_window = ProgressWindow.instantiate()
@ -60,9 +68,12 @@ func _on_generate_system_maps_pressed() -> void:
func _exit_tree() -> void:
remove_custom_type("River")
remove_custom_type("Water System")
remove_custom_type("Waterfall")
remove_custom_type("WaterfallConfiguration")
remove_custom_type("WaterSystem")
remove_custom_type("Buoyant")
remove_node_3d_gizmo_plugin(river_gizmo)
remove_node_3d_gizmo_plugin(waterfall_gizmo)
remove_inspector_plugin(gradient_inspector)
_river_controls.disconnect("mode", Callable(self, "_on_mode_change"))
_river_controls.disconnect("options", Callable(self, "_on_option_change"))
@ -74,9 +85,10 @@ func _exit_tree() -> void:
func _handles(node):
return node is RiverManager or node is WaterSystem
return node is RiverManager or node is WaterfallManager or node is WaterSystem
# TODO - I think this was commented out for 4.0 conversion and isn't needed anymore
#func _edit(node):
# print("edit(), node is: ", node)
# if node is RiverManager:
@ -88,11 +100,12 @@ func _handles(node):
func _on_selection_change() -> void:
_editor_selection = get_editor_interface().get_selection()
#print("_on_selection_change(), Selection: ", _editor_selection)
var selected = _editor_selection.get_selected_nodes()
_hide_water_system_control_panel()
_hide_river_control_panel()
if len(selected) == 0:
return
if selected[0] is RiverManager:
@ -101,22 +114,16 @@ func _on_selection_change() -> void:
_river_controls.menu.debug_view_menu_selected = _edited_node.debug_view
if not _edited_node.is_connected("progress_notified", Callable(self, "_river_progress_notified")):
_edited_node.connect("progress_notified", Callable(self, "_river_progress_notified"))
_hide_water_system_control_panel()
elif selected[0] is WaterfallManager:
_edited_node = selected[0] as WaterfallManager
elif selected[0] is WaterSystem:
# TODO - is there anything we need to add here?
_show_water_system_control_panel()
_edited_node = selected[0] as WaterSystem
_hide_river_control_panel()
else:
print("_edited_node set to null")
_edited_node = null
_hide_river_control_panel()
_hide_water_system_control_panel()
func _on_scene_changed(scene_root) -> void:
# TODO - Hmmm
# print(scene_root)
_hide_river_control_panel()
_hide_water_system_control_panel()
@ -134,28 +141,38 @@ func _on_option_change(option, value) -> void:
if option == "constraint":
constraint = value
if constraint == RiverControls.CONSTRAINTS.COLLIDERS:
WaterHelperMethods.reset_all_colliders(_edited_node.get_tree().root)
# WaterHelperMethods.reset_all_colliders(_edited_node.get_tree().root)
# TODO - figure out if this is needed any more
pass
elif option == "local_mode":
local_editing = value
func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int:
if not _edited_node:
# TODO - This should be updated to the enum when it's fixed https://github.com/godotengine/godot/pull/64465
return 0
return AFTER_GUI_INPUT_PASS
if _edited_node is RiverManager:
return _forward_3d_gui_input_river(camera, event)
elif _edited_node is WaterfallManager:
return AFTER_GUI_INPUT_PASS
return AFTER_GUI_INPUT_PASS
func _forward_3d_gui_input_river(camera: Camera3D, event: InputEvent) -> int:
var global_transform: Transform3D = _edited_node.transform
if _edited_node.is_inside_tree():
global_transform = _edited_node.get_global_transform()
var global_inverse: Transform3D = global_transform.affine_inverse()
if (event is InputEventMouseButton) and (event.button_index == MOUSE_BUTTON_LEFT):
var ray_from = camera.project_ray_origin(event.position)
var ray_dir = camera.project_ray_normal(event.position)
var g1 = global_inverse * (ray_from)
var g2 = global_inverse * (ray_from + ray_dir * 4096)
# Iterate through points to find closest segment
var curve_points = _edited_node.get_curve_points()
var closest_distance = 4096.0
@ -197,7 +214,7 @@ func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int:
if _mode == "select":
if not event.pressed:
river_gizmo.reset()
return 0
return AFTER_GUI_INPUT_PASS
if _mode == "add" and not event.pressed:
# if we don't have a point on the line, we'll calculate a point
# based of a plane of the last point of the curve
@ -217,11 +234,12 @@ func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int:
var new_pos
if constraint == RiverControls.CONSTRAINTS.COLLIDERS:
var space_state = _edited_node.get_world_3d().direct_space_state
var result = space_state.intersect_ray(ray_from, ray_from + ray_dir * 4096)
var ray_params = PhysicsRayQueryParameters3D.create(ray_from, ray_from + ray_dir * 4096)
var result = space_state.intersect_ray(ray_params)
if result:
new_pos = result.position
else:
return 0
return AFTER_GUI_INPUT_PASS
elif constraint == RiverControls.CONSTRAINTS.NONE:
new_pos = plane.intersects_ray(ray_from, ray_from + ray_dir * 4096)
@ -240,8 +258,8 @@ func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int:
if local_editing:
normal = _handle_base_transform.basis * (normal)
var projected : Vector3 = end_pos_global.project(normal)
var direction : Vector3 = sign(projected.dot(normal))
var distance : Vector3 = direction * projected.length()
var direction : float = signf(projected.dot(normal))
var distance : float = direction * projected.length()
plane = Plane(normal, distance)
new_pos = plane.intersects_ray(ray_from, ray_dir)
@ -285,8 +303,7 @@ func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int:
ur.add_undo_property(_edited_node, "valid_flowmap", _edited_node.valid_flowmap)
ur.add_undo_method(_edited_node, "update_configuration_warnings")
ur.commit_action()
# TODO - This should be updated to the enum when it's fixed https://github.com/godotengine/godot/pull/64465
return 1
return AFTER_GUI_INPUT_STOP
elif _edited_node is RiverManager:
# Forward input to river controls. This is cleaner than handling
@ -296,9 +313,7 @@ func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int:
# method needs to be exposed.
# TODO - so this was returning a bool before? Check this
return _river_controls.spatial_gui_input(event)
# TODO - This should be updated to the enum when it's fixed https://github.com/godotengine/godot/pull/64465
return 0
return AFTER_GUI_INPUT_PASS
func _river_progress_notified(progress : float, message : String) -> void:

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends Node3D
@ -103,7 +103,7 @@ var baking_foam_blur : float = 0.02
# Public variables
var curve : Curve3D
var widths := [1.0, 1.0]: set = set_widths
var widths : Array[float] = [1.0, 1.0]: set = set_widths
var valid_flowmap := false
var debug_view : int = 0: set = set_debug_view
var mesh_instance : MeshInstance3D
@ -332,9 +332,6 @@ func _get_property_list() -> Array:
]
var combined_props = props + props2 + props3
# TODO, remember to remove this
# print(var2str(combined_props))
return combined_props
@ -348,37 +345,32 @@ func _set(property: StringName, value) -> bool:
func _get(property : StringName):
#print("in _get(), property: ", property)
if str(property).begins_with("mat_"):
var param_name = str(property).replace("mat_", "")
#print("property name in _get is: ", property)
#print("param name in _get is: ", param_name)
#print ("_material.get_shader_parameter(param_name): ", _material.get_shader_parameter(param_name))
return _material.get_shader_parameter(param_name)
# TODO - This doesn't currently work in Godot 4. https://github.com/godotengine/godot/issues/69335
#func _property_can_revert(property : StringName) -> bool:
# if str(property).begins_with("mat_"):
## if "color" in property:
## # TODO - we are disabling revert for color parameters due to this
## # bug: https://github.com/godotengine/godot/issues/45388
## return false
# var param_name = str(property).replace("mat_", "")
# return _material._property_can_revert(str("shader_param/", param_name))
#
# if not DEFAULT_PARAMETERS.has(property):
# return false
# if get(property) != DEFAULT_PARAMETERS[property]:
# return true
# return false
#
#
#func _property_get_revert(property : StringName):
# if str(property).begins_with("mat_"):
# var param_name = str(property).replace("mat_", "")
# var revert_value = _material._property_get_revert(str("shader_param/", param_name))
# return revert_value
func _property_can_revert(property : StringName) -> bool:
if str(property).begins_with("mat_"):
# if "color" in property:
# # TODO - we are disabling revert for color parameters due to this
# # bug: https://github.com/godotengine/godot/issues/45388
# return false
var param_name = str(property).replace("mat_", "")
return _material.property_can_revert(str("shader_param/", param_name))
if not DEFAULT_PARAMETERS.has(property):
return false
if get(property) != DEFAULT_PARAMETERS[property]:
return true
return false
func _property_get_revert(property : StringName):
if str(property).begins_with("mat_"):
var param_name = str(property).replace("mat_", "")
var revert_value = _material.property_get_revert(str("shader_param/", param_name))
return revert_value
func _init() -> void:
@ -443,12 +435,12 @@ func add_point(position : Vector3, index : int, dir : Vector3 = Vector3.ZERO, wi
if index == -1:
var last_index := curve.get_point_count() - 1
var dist = position.distance_to(curve.get_point_position(last_index))
var new_dir = dir if dir != Vector3.ZERO else (position - curve.get_point_position(last_index) - curve.get_point_out(last_index) ).normalized() * 0.25 * dist
var new_dir :Vector3 = dir if dir != Vector3.ZERO else (position - curve.get_point_position(last_index) - curve.get_point_out(last_index) ).normalized() * 0.25 * dist
curve.add_point(position, -new_dir, new_dir, -1)
widths.append(widths[widths.size() - 1]) # If this is a new point at the end, add a width that's the same as last
else:
var dist = curve.get_point_position(index).distance_to(curve.get_point_position(index + 1))
var new_dir = dir if dir != Vector3.ZERO else (curve.get_point_position(index + 1) - curve.get_point_position(index)).normalized() * 0.25 * dist
var new_dir : Vector3 = dir if dir != Vector3.ZERO else (curve.get_point_position(index + 1) - curve.get_point_position(index)).normalized() * 0.25 * dist
curve.add_point(position, -new_dir, new_dir, index + 1)
var new_width = width if width != 0.0 else (widths[index] + widths[index + 1]) / 2.0
widths.insert(index + 1, new_width) # We set the width to the average of the two surrounding widths
@ -472,6 +464,7 @@ func bake_texture() -> void:
func set_curve_point_position(index : int, position : Vector3) -> void:
print("set curve point position")
curve.set_point_position(index, position)
_generate_river()
@ -487,6 +480,7 @@ func set_curve_point_out(index : int, position : Vector3) -> void:
func set_widths(new_widths) -> void:
print("set widths")
widths = new_widths
if _first_enter_tree:
return
@ -626,7 +620,7 @@ func _generate_river() -> void:
func _generate_flowmap(flowmap_resolution : float) -> void:
WaterHelperMethods.reset_all_colliders(get_tree().root)
#WaterHelperMethods.reset_all_colliders(get_tree().root)
var image := Image.create(flowmap_resolution, flowmap_resolution, true, Image.FORMAT_RGB8)
image.fill(Color(0.0, 0.0, 0.0))

View file

@ -1,10 +1,8 @@
// Copyright © 2022 Kasper Arnklit Frandsen - MIT License
// Copyright © 2023 Kasper Arnklit Frandsen - MIT License
// See `LICENSE.md` included in the source distribution for details.
shader_type spatial;
render_mode depth_draw_always, cull_disabled;
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
// If you are making your own shader, you can customize or add your own
// parameters below and they will automatically get parsed and displayed in
// the River inspector.

View file

@ -1,11 +1,8 @@
// Copyright © 2022 Kasper Arnklit Frandsen - MIT License
// Copyright © 2023 Kasper Arnklit Frandsen - MIT License
// See `LICENSE.md` included in the source distribution for details.
shader_type spatial;
render_mode depth_draw_always, specular_schlick_ggx, cull_disabled;
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
// If you are making your own shader, you can customize or add your own
// parameters below and they will automatically get parsed and displayed in
// the River inspector.
@ -55,6 +52,8 @@ uniform sampler2D i_distmap : hint_default_white;
uniform bool i_valid_flowmap = false;
uniform int i_uv2_sides = 2;
uniform sampler2D depth_texture : hint_depth_texture;
uniform sampler2D screen_texture : hint_screen_texture;
vec3 FlowUVW(vec2 uv_in, vec2 flowVector, vec2 jump, vec3 tiling, float time, bool flowB) {
float phaseOffset = flowB ? 0.5 : 0.0;
@ -183,7 +182,7 @@ void fragment() {
// We do two depth tests, one with the standard SCREEN_UV and one with the distorted
// refraction UVs. We do this to be able to dismiss refractions that are in front
// of objects
float depth_tex = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r;
float depth_tex = textureLod(depth_texture, SCREEN_UV, 0.0).r;
vec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex,1.0);
world_pos.xyz/=world_pos.w;
float water_depth = VERTEX.z - world_pos.z;
@ -205,7 +204,7 @@ void fragment() {
float ref_amount = 1.0 - clamp(clar_t + combined_foam, 0.0, 1.0);
// Depthtest 2
float refracted_depth_tex = textureLod(DEPTH_TEXTURE, ref_ofs, 0.0).r;
float refracted_depth_tex = textureLod(depth_texture, ref_ofs, 0.0).r;
vec4 refracted_world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, refracted_depth_tex, 1.0);
refracted_world_pos.xyz /= refracted_world_pos.w;
float refracted_water_depth = VERTEX.z - refracted_world_pos.z;
@ -225,7 +224,7 @@ void fragment() {
vec3 alb_mix = mix(albedo_color_near.rgb, albedo_color_far.rgb, alb_t);
ALBEDO = mix(alb_mix, foam_color.rgb, combined_foam);
ALBEDO *= 1.0 - ref_amount;
EMISSION += textureLod(SCREEN_TEXTURE, ref_ofs, ROUGHNESS * water_depth).rgb * ref_amount;
EMISSION += textureLod(screen_texture, ref_ofs, ROUGHNESS * water_depth).rgb * ref_amount;
ALPHA = 1.0;
ALPHA *= clamp(1.0 - smoothstep(world_pos.z + edge_fade, world_pos.z, VERTEX.z), 0.0, 1.0);
}

View file

@ -1,4 +1,4 @@
// Copyright © 2022 Kasper Arnklit Frandsen - MIT License
// Copyright © 2023 Kasper Arnklit Frandsen - MIT License
// See `LICENSE.md` included in the source distribution for details.
shader_type spatial;

View file

@ -9,17 +9,42 @@ uniform float flow_distance : hint_range(0.0, 8.0) = 1.0;
uniform float flow_pressure : hint_range(0.0, 8.0) = 1.0;
uniform float flow_max : hint_range(0.0, 8.0) = 4.0;
uniform bool valid_flowmap = false;
uniform int uv2_sides = 2;
varying vec3 binormal_world;
// Converts a color from linear light gamma to sRGB gamma
vec4 fromLinear(vec4 linearRGB)
{
bvec4 cutoff = lessThan(linearRGB, vec4(0.0031308));
vec4 higher = vec4(1.055)*pow(linearRGB, vec4(1.0/2.4)) - vec4(0.055);
vec4 lower = linearRGB * vec4(12.92);
return mix(higher, lower, cutoff);
}
// Converts a color from sRGB gamma to linear light gamma
vec4 toLinear(vec4 sRGB)
{
bvec4 cutoff = lessThan(sRGB, vec4(0.04045));
vec4 higher = pow((sRGB + vec4(0.055))/vec4(1.055), vec4(2.4));
vec4 lower = sRGB/vec4(12.92);
return mix(higher, lower, cutoff);
}
void vertex() {
binormal_world = (MODEL_MATRIX * vec4(BINORMAL, 0.0)).xyz;
}
void fragment() {
vec2 flow_foam_noise = textureLod(flowmap, UV2, 0.0).rg;
vec2 dist_pressure = textureLod(distmap, UV2, 0.0).xy;
vec2 custom_UV = (UV2 + 1.0 / float(uv2_sides)) * (float(uv2_sides) / float(uv2_sides + 2));
vec2 flow_foam_noise = textureLod(flowmap, custom_UV, 0.0).rg;
vec2 dist_pressure = textureLod(distmap, custom_UV, 0.0).xy;
vec2 flow;
float distance_map;
@ -49,5 +74,7 @@ void fragment() {
float sine = sin(rotation);
mat2 rotation_mat = mat2(vec2(cosine, -sine), vec2(sine, cosine));
vec2 new_flow = rotation_mat * flow;
new_flow = toLinear(vec4(new_flow, 0.0, 1.0)).rg;
ALBEDO = vec3((new_flow), 0.0) * 0.5 + 0.5; // repack flowmap
//ALBEDO = vec3(flow, 0.0);
}

View file

@ -5,11 +5,23 @@ uniform float lower_bounds = 0.0;
uniform float upper_bounds = 10.0;
varying vec3 vertex_trans;
// Converts a color from sRGB gamma to linear light gamma
vec4 toLinear(vec4 sRGB)
{
bvec4 cutoff = lessThan(sRGB, vec4(0.04045));
vec4 higher = pow((sRGB + vec4(0.055))/vec4(1.055), vec4(2.4));
vec4 lower = sRGB/vec4(12.92);
return mix(higher, lower, cutoff);
}
void vertex() {
vertex_trans = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
}
void fragment() {
float range = upper_bounds - lower_bounds;
ALBEDO = vec3( clamp((vertex_trans.y - lower_bounds) / range, 0.0, 1.0) );
float height = clamp((vertex_trans.y - lower_bounds) / range, 0.0, 1.0);
//height = toLinear(vec4(vec3(height), 1.0)).r;
ALBEDO = vec3( height );
}

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
@tool
extends SubViewport
@ -7,7 +7,7 @@ const HEIGHT_SHADER_PATH = "res://addons/waterways/shaders/system_renders/system
const FLOW_SHADER_PATH = "res://addons/waterways/shaders/system_renders/system_flow.gdshader"
const ALPHA_SHADER_PATH = "res://addons/waterways/shaders/system_renders/alpha.gdshader"
const RiverManager = preload("./river_manager.gd")
var renderer = SubViewport
var _camera: Camera3D
var _container: Node3D
@ -48,8 +48,7 @@ func grab_height(water_objects: Array[RiverManager], aabb : AABB, resolution : f
await get_tree().process_frame
var height : Image = get_texture().get_image()
var height_result := ImageTexture.new()
height_result.create_from_image(height)
var height_result := ImageTexture.create_from_image(height)
for child in _container.get_children():
_container.remove_child(child)
@ -91,8 +90,7 @@ func grab_alpha(water_objects: Array[RiverManager], aabb: AABB, resolution: floa
await get_tree().process_frame
var alpha : Image = get_texture().get_image()
var alpha_result := ImageTexture.new()
alpha_result.create_from_image(alpha)
var alpha_result := ImageTexture.create_from_image(alpha)
for child in _container.get_children():
_container.remove_child(child)
@ -105,30 +103,32 @@ func grab_flow(water_objects: Array[RiverManager], aabb : AABB, resolution : flo
_camera = $Camera3D as Camera3D
_container = $Container as Node3D
var flow_mat := ShaderMaterial.new()
var flow_shader := load(FLOW_SHADER_PATH) as Shader
flow_mat.shader = flow_shader
for i in water_objects.size():
var flow_mat := ShaderMaterial.new()
var flow_shader := load(FLOW_SHADER_PATH) as Shader
flow_mat.shader = flow_shader
flow_mat.set_shader_parameter("flowmap", water_objects[i].flow_foam_noise)
flow_mat.set_shader_parameter("distmap", water_objects[i].dist_pressure)
flow_mat.set_shader_parameter("flow_base", water_objects[i].get_shader_parameter("flow_base"))
flow_mat.set_shader_parameter("flow_steepness", water_objects[i].get_shader_parameter("flow_steepness"))
flow_mat.set_shader_parameter("flow_distance", water_objects[i].get_shader_parameter("flow_distance"))
flow_mat.set_shader_parameter("flow_pressure", water_objects[i].get_shader_parameter("flow_pressure"))
flow_mat.set_shader_parameter("flow_max", water_objects[i].get_shader_parameter("flow_max"))
flow_mat.set_shader_parameter("valid_flowmap", water_objects[i].get_shader_parameter("i_valid_flowmap"))
flow_mat.set_shader_parameter("uv2_sides", water_objects[i].get_shader_parameter("i_uv2_sides"))
var water_mesh_copy := water_objects[i].mesh_instance.duplicate(true)
_container.add_child(water_mesh_copy)
water_mesh_copy.transform = water_objects[i].transform
water_mesh_copy.material_override = flow_mat
water_mesh_copy.material_override.set_shader_parameter("flowmap", water_objects[i].flow_foam_noise)
water_mesh_copy.material_override.set_shader_parameter("distmap", water_objects[i].dist_pressure)
water_mesh_copy.material_override.set_shader_parameter("flow_base", water_objects[i].get_shader_parameter("flow_base"))
water_mesh_copy.material_override.set_shader_parameter("flow_steepness", water_objects[i].get_shader_parameter("flow_steepness"))
water_mesh_copy.material_override.set_shader_parameter("flow_distance", water_objects[i].get_shader_parameter("flow_distance"))
water_mesh_copy.material_override.set_shader_parameter("flow_pressure", water_objects[i].get_shader_parameter("flow_pressure"))
water_mesh_copy.material_override.set_shader_parameter("flow_max", water_objects[i].get_shader_parameter("flow_max"))
water_mesh_copy.material_override.set_shader_parameter("valid_flowmap", water_objects[i].get_shader_parameter("i_valid_flowmap"))
var longest_axis := aabb.get_longest_axis_index()
match longest_axis:
Vector3.AXIS_X:
_camera.position = aabb.position + Vector3(aabb.size.x / 2.0, aabb.size.y + 1.0, aabb.size.x / 2.0)
Vector3.AXIS_Y:
# This shouldn't happen, we might need some code to handle if it does
# This shouldn't happen, we might need some code to handle if it does - TODO
pass
Vector3.AXIS_Z:
_camera.position = aabb.position + Vector3(aabb.size.z / 2.0, aabb.size.y + 1.0, aabb.size.z / 2.0)
@ -142,8 +142,7 @@ func grab_flow(water_objects: Array[RiverManager], aabb : AABB, resolution : flo
await get_tree().process_frame
var flow : Image = get_texture().get_image()
var flow_result := ImageTexture.new()
flow_result.create_from_image(flow)
var flow_result := ImageTexture.create_from_image(flow)
for child in _container.get_children():
_container.remove_child(child)

View file

@ -3,8 +3,10 @@
[ext_resource type="Script" path="res://addons/waterways/system_map_renderer.gd" id="1"]
[node name="SystemMatRenderer" type="SubViewport"]
own_world_3d = true
transparent_bg = true
debug_draw = 1
use_hdr_2d = true
gui_disable_input = true
render_target_update_mode = 1
script = ExtResource("1")

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/flow_offset_noise.png-f3f9e08ae624dc7c49a4bff
[params]
compress/mode=1
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=2
compress/channel_pack=0
mipmaps/generate=true

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/lava_normal_bump.png-7ae873772cb659577ce76e96
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=2
compress/channel_pack=0
mipmaps/generate=true

View file

@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/water1_normal_bump.png-1e68aa6d8e854a1982405b
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=2
compress/channel_pack=0
mipmaps/generate=true

View file

@ -1,4 +1,4 @@
# Copyright © 2022 Kasper Arnklit Frandsen - MIT License
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
#const RiverManager = preload("./river_manager.gd")
@ -25,16 +25,8 @@ static func bary2cart(a : Vector3, b : Vector3, c: Vector3, barycentric: Vector3
static func point_in_bariatric(v : Vector3) -> bool:
return 0 <= v.x and v.x <= 1 and 0 <= v.y and v.y <= 1 and 0 <= v.z and v.z <= 1;
static func reset_all_colliders(node):
for n in node.get_children():
if n.get_child_count() > 0:
reset_all_colliders(n)
if n is CollisionShape3D:
if n.disabled == false:
n.disabled = true
n.disabled = false
static func sum_array(array : Array) -> float:
static func sum_array(array : Array[float]) -> float:
var sum := 0.0