-
Notifications
You must be signed in to change notification settings - Fork 90
Add the ToHeight2D/3D node, used to create side-view or 3D terrain.
#403
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
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
60da53a
Add the ToHeight node
BenjaTK 17d3f88
Add description and 2D/3D variants
BenjaTK f7d27c4
Add documentation.
BenjaTK e58613d
Fix `_get_data` type
BenjaTK 3dc11eb
Add tests
BenjaTK c392490
Fix unused argument warning
BenjaTK 43f3409
Add gradient
BenjaTK 876ed4c
Update to_height_2d_and_3d.gd
BenjaTK 33e5c5e
Change gradient value
BenjaTK 86c8677
Move `z_range` check outside loop
BenjaTK 3b24d3c
Update to_height_2d_and_3d.gd
BenjaTK 7b0551b
Remove print
BenjaTK File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
addons/gaea/graph/graph_nodes/root/data/transformation/to_height.gd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| @tool | ||
| class_name GaeaNodeToHeight | ||
| extends GaeaNodeResource | ||
| ## Transforms [param reference_data] into a new data grid where the height of each column is determined by [param height_offset] + ([param reference_data] * [param displacement_intensity]) | ||
| ## | ||
| ## For each cell in [param reference_data]'s [param reference_y] row, it'll get the [code]float[/code] value, | ||
| ## multiply it by [param displacement_intensity] and add [param height_offset] to it. This will be | ||
| ## the column's height, and every cell below that height (inclusive) will be full while every cell above | ||
| ## will be empty.[br][br] | ||
| ## This functions to create a heightmap, which can be used to create 2D side-view or | ||
| ## 3D terrain.[br][br] | ||
| ## [b]Note: Keep in mind the y axis in Godot is negative for up in 2D and down in 3D.[/b] | ||
|
|
||
| enum Type { | ||
| TYPE_2D, ## Referenced data will only take into account the x coordinate of the cell. | ||
| TYPE_3D ## Referenced data will take into account both the x and the z coordinates of the cell. | ||
| } | ||
|
|
||
|
|
||
| func _get_title() -> String: | ||
| return "ToHeight" | ||
|
|
||
|
|
||
| func _get_description() -> String: | ||
| var desc: String = "Transforms [param reference_data] into a new data grid where the height of each column is determined by\ | ||
| [param height_offset] + ([param reference_data] * [param displacement_intensity]).\n" | ||
| match get_enum_selection(0): | ||
| Type.TYPE_2D: | ||
| desc += "\nReferences all the x values of the [param reference_y] row." | ||
| Type.TYPE_3D: | ||
| desc += "\nReferences all the x,z values of the [param reference_y] row." | ||
| return desc | ||
|
|
||
|
|
||
| func _get_tree_items() -> Array[GaeaNodeResource]: | ||
| var items: Array[GaeaNodeResource] | ||
| for type in Type.values(): | ||
| var item: GaeaNodeToHeight = get_script().new() | ||
| item.set_tree_name_override(_get_title() + _get_enum_option_display_name(0, type)) | ||
| item.set_default_enum_value_override(0, type) | ||
| items.append(item) | ||
|
|
||
| return items | ||
|
|
||
|
|
||
| func _get_enums_count() -> int: | ||
| return 1 | ||
|
|
||
|
|
||
| func _get_enum_options(_enum_idx: int) -> Dictionary: | ||
| return Type | ||
|
|
||
|
|
||
| func _get_enum_option_display_name(_enum_idx: int, option_value: int) -> String: | ||
| return Type.find_key(option_value).trim_prefix("TYPE_") | ||
|
|
||
|
|
||
|
|
||
| func _get_arguments_list() -> Array[StringName]: | ||
| return [&"reference_data", &"reference_y", | ||
| &"height_offset", &"displacement_intensity", | ||
| &"gradient_intensity"] | ||
|
|
||
|
|
||
| func _get_argument_type(arg_name: StringName) -> GaeaValue.Type: | ||
| match arg_name: | ||
| &"reference_data": return GaeaValue.Type.DATA | ||
| &"gradient_intensity": return GaeaValue.Type.FLOAT | ||
| _: return GaeaValue.Type.INT | ||
|
|
||
|
|
||
| func _get_argument_default_value(arg_name: StringName) -> Variant: | ||
| match arg_name: | ||
| &"displacement_intensity": return 16 | ||
| &"gradient_intensity": return 1.0 | ||
| return super(arg_name) | ||
|
|
||
|
|
||
|
|
||
| func _get_output_ports_list() -> Array[StringName]: | ||
| return [&"data"] | ||
|
|
||
|
|
||
| func _get_output_port_type(_output_name: StringName) -> GaeaValue.Type: | ||
| return GaeaValue.Type.DATA | ||
|
|
||
|
|
||
| func _get_data(_output_port: StringName, area: AABB, graph: GaeaGraph) -> Dictionary: | ||
| var reference_data: Dictionary = _get_arg(&"reference_data", area, graph) | ||
| var row: int = _get_arg(&"reference_y", area, graph) | ||
| var height_offset: int = _get_arg(&"height_offset", area, graph) | ||
| var displacement: int = _get_arg(&"displacement_intensity", area, graph) | ||
| var gradient_intensity: float = _get_arg(&"gradient_intensity", area, graph) | ||
| var data: Dictionary[Vector3i, float] = {} | ||
| var type: Type = get_enum_selection(0) as Type | ||
|
|
||
| var remap_offset: float = 0.0 | ||
| if not is_zero_approx(gradient_intensity): | ||
| remap_offset = 100.0 / gradient_intensity | ||
|
|
||
| var z_range: Array = [0] if (type == Type.TYPE_2D) else (_get_axis_range(Vector3i.AXIS_Z, area)) | ||
| for x in _get_axis_range(Vector3i.AXIS_X, area): | ||
| if not reference_data.has(Vector3i(x, row, 0)): | ||
| continue | ||
| for z in z_range: | ||
| var height: int = floor(reference_data[Vector3i(x, row, z)] * displacement + height_offset) | ||
| for y in _get_axis_range(Vector3i.AXIS_Y, area): | ||
| if y >= -height and type == Type.TYPE_2D: | ||
| data[Vector3i(x, y, z)] = 1.0 if is_zero_approx(remap_offset) else remap( | ||
| y, -height + remap_offset, -height, 0, 1.0 | ||
| ) | ||
| elif y <= height and type == Type.TYPE_3D: | ||
| data[Vector3i(x, y, z)] = 1.0 if is_zero_approx(remap_offset) else remap( | ||
| y, height, height - remap_offset, 1.0, 0.0 | ||
| ) | ||
| return data | ||
1 change: 1 addition & 0 deletions
1
addons/gaea/graph/graph_nodes/root/data/transformation/to_height.gd.uid
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://b0xqvegteqx7c |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| extends GdUnitTestSuite | ||
|
|
||
|
|
||
| const AREA: AABB = AABB(Vector3.ZERO, Vector3(1, 4, 1) * 16) | ||
| const EXPECTED_HASH_2D: int = 3725516071 | ||
| const EXPECTED_HASH_3D: int = 2178371583 | ||
|
|
||
| var reference_data: Dictionary = {} | ||
| var node: GaeaNodeToHeight | ||
|
|
||
|
|
||
| func before() -> void: | ||
| var noise: FastNoiseLite = FastNoiseLite.new() | ||
| for x in range(AREA.position.x, AREA.end.x): | ||
| for z in range(AREA.position.z, AREA.end.z): | ||
| reference_data[Vector3i(x, 1, z)] = noise.get_noise_3d(x, 0, z) | ||
| node = GaeaNodeToHeight.new() | ||
| node.set_argument_value(&"reference_data", reference_data) | ||
| node.set_argument_value(&"reference_y", 1) | ||
|
|
||
|
|
||
| func test_2d() -> void: | ||
| node.set_enum_value(0, GaeaNodeToHeight.Type.TYPE_2D) | ||
| node.set_argument_value(&"height_offset", -4) | ||
| var generated_data: Dictionary = node._get_data(&"data", AREA, null) | ||
| assert_dict(generated_data)\ | ||
| .override_failure_message("Empty result from [b]GaeaNodeToHeight2D[/b].")\ | ||
| .is_not_empty() | ||
| assert_int(generated_data.hash())\ | ||
| .override_failure_message("Unexpected result from [b]GaeaNodeToHeight2D[/b].")\ | ||
| .append_failure_message("Generated: %s\nExpected: %s" % [generated_data.hash(), EXPECTED_HASH_2D])\ | ||
| .is_equal(EXPECTED_HASH_2D) | ||
|
|
||
|
|
||
| func test_3d() -> void: | ||
| node.set_enum_value(0, GaeaNodeToHeight.Type.TYPE_3D) | ||
| node.set_argument_value(&"height_offset", 4) | ||
| var generated_data: Dictionary = node._get_data(&"data", AREA, null) | ||
| assert_dict(generated_data)\ | ||
| .override_failure_message("Empty result from [b]GaeaNodeToHeight3D[/b].")\ | ||
| .is_not_empty() | ||
| assert_int(generated_data.hash())\ | ||
| .override_failure_message("Unexpected result from [b]GaeaNodeToHeight3D[/b].")\ | ||
| .append_failure_message("Generated: %s\nExpected: %s" % [generated_data.hash(), EXPECTED_HASH_3D])\ | ||
| .is_equal(EXPECTED_HASH_3D) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://ds4py82j4mpkj |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.