diff --git a/modules/mesh_data_resource/editor/addon/widgets/EditorZoomWidget.gd b/modules/mesh_data_resource/editor/addon/widgets/EditorZoomWidget.gd deleted file mode 100644 index c0579b6c0..000000000 --- a/modules/mesh_data_resource/editor/addon/widgets/EditorZoomWidget.gd +++ /dev/null @@ -1,218 +0,0 @@ -tool -extends HBoxContainer - -#This is a port of godot 4.0's EditorZoomWidget - -#/*************************************************************************/ -#/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -#/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -#/* */ -#/* Permission is hereby granted, free of charge, to any person obtaining */ -#/* a copy of this software and associated documentation files (the */ -#/* "Software"), to deal in the Software without restriction, including */ -#/* without limitation the rights to use, copy, modify, merge, publish, */ -#/* distribute, sublicense, and/or sell copies of the Software, and to */ -#/* permit persons to whom the Software is furnished to do so, subject to */ -#/* the following conditions: */ -#/* */ -#/* The above copyright notice and this permission notice shall be */ -#/* included in all copies or substantial portions of the Software. */ -#/* */ -#/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -#/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -#/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -#/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -#/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -#/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -#/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#/*************************************************************************/ - -var zoom_minus : Button -var zoom_reset : Button -var zoom_plus : Button - -var EDSCALE : float = 1 - -export(float) var zoom : float = 1.0 setget set_zoom, get_zoom - -signal zoom_changed(zoom) - -func _init() -> void: - # Zoom buttons - zoom_minus = Button.new() - zoom_minus.set_flat(true) - add_child(zoom_minus) - zoom_minus.connect("pressed", self, "_button_zoom_minus") - zoom_minus.set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_minus", tr("Zoom Out"), KEY_MASK_CMD | KEY_MINUS)) - zoom_minus.set_focus_mode(FOCUS_NONE) - - zoom_reset = Button.new() - zoom_reset.set_flat(true) - add_child(zoom_reset) - zoom_reset.add_constant_override("outline_size", 1) - zoom_reset.add_color_override("font_outline_color", Color(0, 0, 0)) - zoom_reset.add_color_override("font_color", Color(1, 1, 1)) - zoom_reset.connect("pressed", self, "_button_zoom_reset") - zoom_reset.set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", tr("Zoom Reset"), KEY_MASK_CMD | KEY_0)) - zoom_reset.set_focus_mode(FOCUS_NONE) - #Prevent the button's size from changing when the text size changes - zoom_reset.set_custom_minimum_size(Vector2(75, 0)) - - zoom_plus = Button.new() - zoom_plus.set_flat(true) - add_child(zoom_plus) - zoom_plus.connect("pressed", self, "_button_zoom_plus") - zoom_plus.set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", tr("Zoom In"), KEY_MASK_CMD | KEY_EQUAL)) # Usually direct access key for PLUS - zoom_plus.set_focus_mode(FOCUS_NONE) - - _update_zoom_label() - - add_constant_override("separation", round(-8)) - -func get_zoom() -> float: - return zoom - -func set_zoom(p_zoom : float) -> void: - if (p_zoom > 0 && p_zoom != zoom): - zoom = p_zoom; - _update_zoom_label(); - -func set_zoom_by_increments(p_increment_count : int, p_integer_only : bool) -> void: - # Remove editor scale from the index computation. - var zoom_noscale : float = zoom / max(1, EDSCALE) - var CMP_EPSILON : float = 0.00001 - - if (p_integer_only): - # Only visit integer scaling factors above 100%, and fractions with an integer denominator below 100% - # (1/2 = 50%, 1/3 = 33.33%, 1/4 = 25%, …). - # This is useful when working on pixel art projects to avoid distortion. - # This algorithm is designed to handle fractional start zoom values correctly - # (e.g. 190% will zoom up to 200% and down to 100%). - if (zoom_noscale + p_increment_count * 0.001 >= 1.0 - CMP_EPSILON): - # New zoom is certain to be above 100%. - if (p_increment_count >= 1): - # Zooming. - set_zoom(floor(zoom_noscale + p_increment_count) * max(1, EDSCALE)) - else: - # Dezooming. - set_zoom(ceil(zoom_noscale + p_increment_count) * max(1, EDSCALE)) - else: - if (p_increment_count >= 1): - # Zooming. Convert the current zoom into a denominator. - var new_zoom : float = 1.0 / ceil(1.0 / zoom_noscale - p_increment_count) - if (is_equal_approx(zoom_noscale, new_zoom)): - # New zoom is identical to the old zoom, so try again. - # This can happen due to floating-point precision issues. - new_zoom = 1.0 / ceil(1.0 / zoom_noscale - p_increment_count - 1) - - set_zoom(new_zoom * max(1, EDSCALE)); - else: - # Dezooming. Convert the current zoom into a denominator. - var new_zoom : float = 1.0 / floor(1.0 / zoom_noscale - p_increment_count) - if (is_equal_approx(zoom_noscale, new_zoom)): - # New zoom is identical to the old zoom, so try again. - # This can happen due to floating-point precision issues. - new_zoom = 1.0 / floor(1.0 / zoom_noscale - p_increment_count + 1) - - set_zoom(new_zoom * max(1, EDSCALE)) - else: - # Base increment factor defined as the twelveth root of two. - # This allow a smooth geometric evolution of the zoom, with the advantage of - # visiting all integer power of two scale factors. - # note: this is analogous to the 'semitones' interval in the music world - # In order to avoid numerical imprecisions, we compute and edit a zoom index - # with the following relation: zoom = 2 ^ (index / 12) - - if (zoom < CMP_EPSILON || p_increment_count == 0): - return - - # zoom = 2**(index/12) => log2(zoom) = index/12 - var closest_zoom_index : float = round(log(zoom_noscale) * 12.0 / log(2.0)) - - var new_zoom_index : float = closest_zoom_index + p_increment_count - var new_zoom : float = pow(2.0, new_zoom_index / 12.0) - - # Restore Editor scale transformation - new_zoom *= max(1, EDSCALE) - - set_zoom(new_zoom) - - -func _update_zoom_label() -> void: - var zoom_text : String = "" - - # The zoom level displayed is relative to the editor scale - # (like in most image editors). Its lower bound is clamped to 1 as some people - # lower the editor scale to increase the available real estate, - # even if their display doesn't have a particularly low DPI. - - if (zoom >= 10): - # Don't show a decimal when the zoom level is higher than 1000 %. - #zoom_text = (rtos(round((zoom / max(1, EDSCALE)) * 100))) + " %" - zoom_text = (String(round((zoom / max(1, EDSCALE)) * 100))) + " %" - else: - var v : float = (zoom / max(1, EDSCALE)) * 100 - var val : float = floor(v / 0.1 + 0.5) * 0.1 - -# zoom_text = (rtos(val)) + " %" - zoom_text = (String(val)) + " %" - - zoom_reset.set_text(zoom_text) - -func _button_zoom_minus() -> void: - set_zoom_by_increments(-6, Input.is_key_pressed(KEY_ALT)); - emit_signal("zoom_changed", zoom); - -func _button_zoom_reset() -> void: - set_zoom(1.0 * max(1, EDSCALE)); - emit_signal("zoom_changed", zoom); - -func _button_zoom_plus() -> void: - set_zoom_by_increments(6, Input.is_key_pressed(KEY_ALT)); - emit_signal("zoom_changed", zoom); - -func _notification(p_what : int) -> void: - if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED): - zoom_minus.icon = get_icon("ZoomLess", "EditorIcons") - zoom_plus.icon = get_icon("ZoomMore", "EditorIcons") - -#from godot editor/editor_Settings.cpp -func ED_SHORTCUT(p_path : String, p_name : String, p_keycode : int, editor_settings : EditorSettings = null) -> ShortCut: - if OS.get_name() == "OSX": - # Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS - if (p_keycode == KEY_DELETE): - p_keycode = KEY_MASK_CMD | KEY_BACKSPACE - - var ie : InputEventKey = null - if (p_keycode): - ie = InputEventKey.new() - - ie.set_unicode(p_keycode & KEY_CODE_MASK) - ie.set_scancode(p_keycode & KEY_CODE_MASK) - ie.set_shift(bool(p_keycode & KEY_MASK_SHIFT)) - ie.set_alt(bool(p_keycode & KEY_MASK_ALT)) - ie.set_control(bool(p_keycode & KEY_MASK_CTRL)) - ie.set_metakey(bool(p_keycode & KEY_MASK_META)) - - if (!editor_settings): - var sc : ShortCut - sc = ShortCut.new() - sc.set_name(p_name) - sc.set_shortcut(ie) - sc.set_meta("original", ie) - return sc - - var sc : ShortCut = editor_settings.get_shortcut(p_path) - if (sc.is_valid()): - sc.set_name(p_name); #keep name (the ones that come from disk have no name) - sc.set_meta("original", ie); #to compare against changes - return sc; - - sc = ShortCut.new() - sc.set_name(p_name) - sc.set_shortcut(ie) - sc.set_meta("original", ie) #to compare against changes - editor_settings.add_shortcut(p_path, sc) - - return sc - diff --git a/modules/mesh_data_resource/editor/addon/widgets/EditorZoomWidget.tscn b/modules/mesh_data_resource/editor/addon/widgets/EditorZoomWidget.tscn deleted file mode 100644 index 5de87a918..000000000 --- a/modules/mesh_data_resource/editor/addon/widgets/EditorZoomWidget.tscn +++ /dev/null @@ -1,8 +0,0 @@ -[gd_scene load_steps=2 format=2] - -[ext_resource path="res://addons/world_generator/widgets/EditorZoomWidget.gd" type="Script" id=1] - -[node name="EditorZoomWidget" type="HBoxContainer"] -anchor_right = 1.0 -anchor_bottom = 1.0 -script = ExtResource( 1 ) diff --git a/modules/mesh_data_resource/editor/addon/widgets/flex_grid_container.gd b/modules/mesh_data_resource/editor/addon/widgets/flex_grid_container.gd deleted file mode 100644 index df4cb9eaf..000000000 --- a/modules/mesh_data_resource/editor/addon/widgets/flex_grid_container.gd +++ /dev/null @@ -1,207 +0,0 @@ -tool -extends Container - -#From https://github.com/EricEzaM/godot-color-palette - -# MIT License -# -# Copyright (c) 2020 Eric M -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - -var columns: int = 1 setget set_columns -var _min_x : int = 0 - -func _notification(p_what): - match p_what: - NOTIFICATION_SORT_CHILDREN: - var col_minw: Dictionary # Max of min_width of all controls in each col (indexed by col). - var row_minh: Dictionary # Max of min_height of all controls in each row (indexed by row). - var col_expanded: Array # Columns which have the SIZE_EXPAND flag set. - var row_expanded: Array # Rows which have the SIZE_EXPAND flag set. - - var hsep = get_constant("hseparation", "GridContainer") - var vsep = get_constant("vseparation", "GridContainer") - - var min_columns = 1 - _min_x = 0 - - if get_child_count() > 0: - min_columns = int(floor(rect_size.x / (get_child(0).get_combined_minimum_size().x + hsep))) - - self.columns = min_columns - - var max_col = min(get_child_count(), columns) - var max_row = ceil(float(get_child_count()) / float(columns)) - -# Compute the per-column/per-row data. - var valid_controls_index = 0 - for i in range(get_child_count()): - var c: Control = get_child(i) - if !c or !c.is_visible_in_tree(): - continue - - var row = valid_controls_index / columns - var col = valid_controls_index % columns - valid_controls_index += 1 - - var ms: Vector2 = c.get_combined_minimum_size() - - if _min_x < ms.x: - _min_x = ms.x - - if col_minw.has(col): - col_minw[col] = max(col_minw[col], ms.x) - else: - col_minw[col] = ms.x - if row_minh.has(row): - row_minh[row] = max(row_minh[row], ms.y) - else: - row_minh[row] = ms.y - - if c.get_h_size_flags() & SIZE_EXPAND: - col_expanded.push_front(col) - - if c.get_v_size_flags() & SIZE_EXPAND: - row_expanded.push_front(row) - -# Consider all empty columns expanded. - for i in range(valid_controls_index, columns): - col_expanded.push_front(i) - -# Evaluate the remaining space for expanded columns/rows. - var remaining_space: Vector2 = get_size() - - for e in col_minw.keys(): - if !col_expanded.has(e): - remaining_space.x -= col_minw.get(e) - - for e in row_minh.keys(): - if !row_expanded.has(e): - remaining_space.y -= row_minh.get(e) - - remaining_space.y -= vsep * max(max_row - 1, 0) - remaining_space.x -= hsep * max(max_col - 1, 0) - - var can_fit = false - while !can_fit && col_expanded.size() > 0: -# Check if all minwidth constraints are OK if we use the remaining space. - can_fit = true - var max_index = col_expanded.front() - - for e in col_expanded: - if col_minw.has(e): - if col_minw[e] > col_minw[max_index]: - max_index = e - if can_fit && (remaining_space.x / col_expanded.size()) < col_minw[e]: - can_fit = false - -# If not, the column with maximum minwidth is not expanded. - if (!can_fit): - col_expanded.erase(max_index) - remaining_space.x -= col_minw[max_index] - - can_fit = false - while !can_fit && row_expanded.size() > 0: -# Check if all minheight constraints are OK if we use the remaining space. - can_fit = true - var max_index = row_expanded.front() - - for e in row_expanded: - if row_minh[e] > row_minh[max_index]: - max_index = e - if can_fit && (remaining_space.y / row_expanded.size()) < row_minh[e]: - can_fit = false - -# If not, the row with maximum minheight is not expanded. - if (!can_fit): - row_expanded.erase(max_index) - remaining_space.y -= row_minh[max_index] - -# Finally, fit the nodes. - var col_expand = remaining_space.x / col_expanded.size() if col_expanded.size() > 0 else 0 - var row_expand = remaining_space.y / row_expanded.size() if row_expanded.size() > 0 else 0 - - var col_ofs = 0 - var row_ofs = 0 - - valid_controls_index = 0 - for i in range(get_child_count()): - var c: Control = get_child(i) - if (!c || !c.is_visible_in_tree()): - continue - var row = valid_controls_index / columns - var col = valid_controls_index % columns - valid_controls_index += 1 - - if (col == 0): - col_ofs = 0 - if (row > 0): - row_ofs += (row_expand if row_expanded.has(row - 1) else row_minh[row - 1]) + vsep - - var p = Vector2(col_ofs, row_ofs) - var s = Vector2(col_expand if col_expanded.has(col) else col_minw[col], row_expand if row_expanded.has(row) else row_minh[row]) - - fit_child_in_rect(c, Rect2(p, s)) - - col_ofs += s.x + hsep - - NOTIFICATION_THEME_CHANGED: - minimum_size_changed() - -func _get_minimum_size(): -# Only worry about max height, not width (since it does width automatically) - var row_minh: Dictionary - - var vsep = get_constant("vseparation", "GridContainer") - - var max_row = 0 - - var valid_controls_index = 0 - for i in range(get_child_count()): - - var c: Control = get_child(i) - if !c or !c.is_visible(): - continue - var row = valid_controls_index / columns - valid_controls_index += 1 - - var ms = c.get_combined_minimum_size() - - if row_minh.has(row): - row_minh[row] = max(row_minh[row], ms.y) - else: - row_minh[row] = ms.y - max_row = max(row, max_row) - - var ms: Vector2 - ms.x = _min_x - - for e in row_minh.keys(): - ms.y += row_minh.get(e) - - ms.y += vsep * max_row - - return ms - - -func set_columns(p_columns: int): - columns = p_columns - minimum_size_changed() diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_editor.cpp b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_editor.cpp new file mode 100644 index 000000000..74ae03caa --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_editor.cpp @@ -0,0 +1,181 @@ +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "mdr_uv_rect_editor.h" + +#include "editor/editor_plugin.h" +#include "../../mesh_data_resource.h" +#include "../../nodes/mesh_data_instance.h" + +void MDRUVRectEditor::set_plugin(EditorPlugin *plugin) { + //$ScrollContainer/MarginContainer/RectView.set_plugin(plugin) +} + +void MDRUVRectEditor::set_mesh_data_resource(Ref a) { + //$ScrollContainer/MarginContainer/RectView.set_mesh_data_resource(a) +} +void MDRUVRectEditor::set_mesh_data_instance(MeshDataInstance *a) { + //$ScrollContainer/MarginContainer/RectView.set_mesh_data_instance(a) +} +void MDRUVRectEditor::ok_pressed() { + //$ScrollContainer/MarginContainer/RectView.ok_pressed() +} +void MDRUVRectEditor::cancel_pressed() { + //$ScrollContainer/MarginContainer/RectView.cancel_pressed() +} + +MDRUVRectEditor::MDRUVRectEditor() { + /* + +[gd_scene load_steps=8 format=2] + +[ext_resource path="res://addons/mesh_data_resource_editor/uv_editor/RectEditor.gd" type="Script" id=1] +[ext_resource path="res://addons/mesh_data_resource_editor/widgets/EditorZoomWidget.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/mesh_data_resource_editor/uv_editor/RectView.gd" type="Script" id=3] +[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_v_mirror.png" type="Texture" id=4] +[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_h_mirror.png" type="Texture" id=5] +[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_rot_right.png" type="Texture" id=6] +[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_rot_left.png" type="Texture" id=7] + +[node name="UVEditor" type="PanelContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 1017.0 +margin_bottom = 593.0 + +[node name="MarginContainer" type="MarginContainer" parent="ScrollContainer"] +margin_right = 700.0 +margin_bottom = 700.0 +custom_constants/margin_right = 50 +custom_constants/margin_top = 50 +custom_constants/margin_left = 50 +custom_constants/margin_bottom = 50 + +[node name="RectView" type="Control" parent="ScrollContainer/MarginContainer"] +margin_left = 50.0 +margin_top = 50.0 +margin_right = 650.0 +margin_bottom = 650.0 +rect_min_size = Vector2( 600, 600 ) +script = ExtResource( 3 ) +zoom_widget_path = NodePath("../../../Control/HBoxContainer/EditorZoomWidget") +mirror_horizontal_button_path = NodePath("../../../Control/HBoxContainer/HorizontalMirror") +mirror_vertical_button_path = NodePath("../../../Control/HBoxContainer/VerticalMirror") +rotate_left_button_path = NodePath("../../../Control/HBoxContainer/RotLeft") +rotate_amount_spinbox_path = NodePath("../../../Control/HBoxContainer/SpinBox") +rotate_right_button_path = NodePath("../../../Control/HBoxContainer/RotRight") + +[node name="Control" type="VBoxContainer" parent="."] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 1017.0 +margin_bottom = 593.0 +mouse_filter = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="Control"] +margin_right = 1010.0 +margin_bottom = 24.0 +mouse_filter = 2 +size_flags_horizontal = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="EditorZoomWidget" parent="Control/HBoxContainer" instance=ExtResource( 2 )] +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_right = 115.0 +margin_bottom = 24.0 +custom_constants/separation = -8 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VSeparator2" type="VSeparator" parent="Control/HBoxContainer"] +margin_left = 119.0 +margin_right = 123.0 +margin_bottom = 24.0 + +[node name="HorizontalMirror" type="Button" parent="Control/HBoxContainer"] +margin_left = 127.0 +margin_right = 155.0 +margin_bottom = 24.0 +hint_tooltip = "Mirror the selected island horizontally.." +icon = ExtResource( 5 ) + +[node name="VerticalMirror" type="Button" parent="Control/HBoxContainer"] +margin_left = 159.0 +margin_right = 187.0 +margin_bottom = 24.0 +hint_tooltip = "Mirror the selected island vertically." +icon = ExtResource( 4 ) + +[node name="VSeparator" type="VSeparator" parent="Control/HBoxContainer"] +margin_left = 191.0 +margin_right = 195.0 +margin_bottom = 24.0 + +[node name="RotLeft" type="Button" parent="Control/HBoxContainer"] +margin_left = 199.0 +margin_right = 227.0 +margin_bottom = 24.0 +hint_tooltip = "Rotate left." +icon = ExtResource( 7 ) + +[node name="SpinBox" type="SpinBox" parent="Control/HBoxContainer"] +margin_left = 231.0 +margin_right = 305.0 +margin_bottom = 24.0 +hint_tooltip = "Rotate amount in degrees." +max_value = 360.0 +value = 45.0 +allow_greater = true +allow_lesser = true + +[node name="RotRight" type="Button" parent="Control/HBoxContainer"] +margin_left = 309.0 +margin_right = 337.0 +margin_bottom = 24.0 +hint_tooltip = "Rotate right." +icon = ExtResource( 6 ) + + + */ +} + +MDRUVRectEditor::~MDRUVRectEditor() { +} + +void MDRUVRectEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("ok_pressed"), &MDRUVRectEditor::ok_pressed); + ClassDB::bind_method(D_METHOD("cancel_pressed"), &MDRUVRectEditor::cancel_pressed); +} diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_editor.h b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_editor.h new file mode 100644 index 000000000..055fc8002 --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_editor.h @@ -0,0 +1,50 @@ +#ifndef MDR_UV_RECT_EDITOR_H +#define MDR_UV_RECT_EDITOR_H + +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "core/reference.h" +#include "scene/gui/panel_container.h" + +class EditorPlugin; +class MeshDataResource; +class MeshDataInstance; + +class MDRUVRectEditor : public PanelContainer { + GDCLASS(MDRUVRectEditor, PanelContainer); + +public: + //void set_plugin(EditorPlugin *plugin); + void set_mesh_data_resource(Ref a); + void set_mesh_data_instance(MeshDataInstance *a); + void ok_pressed(); + void cancel_pressed(); + + MDRUVRectEditor(); + ~MDRUVRectEditor(); + +protected: + static void _bind_methods(); +}; + +#endif diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.cpp b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.cpp new file mode 100644 index 000000000..59cc59b7c --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.cpp @@ -0,0 +1,324 @@ +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "mdr_uv_rect_view.h" + +#include "scene/gui/control.h" + +void MDRUVRectView::set_plugin(EditorPlugin *plugin) { + /* + _plugin = plugin + + _undo_redo = _plugin.get_undo_redo() + */ +} +void MDRUVRectView::set_mesh_data_resource(Ref a) { + /* +_mdr = a + */ +} +void MDRUVRectView::set_mesh_data_instance(MeshDataInstance *a) { + /* +_background_texture = null + + if a: + _background_texture = a.texture + */ +} +void MDRUVRectView::set_selected(Control *node) { + /* +if selected_rect && is_instance_valid(selected_rect): + selected_rect.set_selected(false) + + selected_rect = node + + if selected_rect: + selected_rect.set_selected(true) + */ +} + +void MDRUVRectView::store_uvs() { + /* +_stored_uvs.resize(0) + + if !_mdr: + return + + var arrays : Array = _mdr.get_array() + + if arrays.size() != ArrayMesh.ARRAY_MAX: + return + + if arrays[ArrayMesh.ARRAY_TEX_UV] == null: + return + + # Make sure it gets copied + _stored_uvs.append_array(arrays[ArrayMesh.ARRAY_TEX_UV]) + */ +} +PoolVector2Array MDRUVRectView::get_uvs(Ref mdr) { + /* +if !_mdr: + return PoolVector2Array() + + var arrays : Array = _mdr.get_array() + + if arrays.size() != ArrayMesh.ARRAY_MAX: + return PoolVector2Array() + + if arrays[ArrayMesh.ARRAY_TEX_UV] == null: + return PoolVector2Array() + + return arrays[ArrayMesh.ARRAY_TEX_UV] + */ +} +void MDRUVRectView::apply_uvs(Ref mdr, PoolVector2Array stored_uvs) { + /* +if !_mdr: + return + + var arrays : Array = _mdr.get_array() + + if arrays.size() != ArrayMesh.ARRAY_MAX: + return + + if arrays[ArrayMesh.ARRAY_TEX_UV] == null: + return + + arrays[ArrayMesh.ARRAY_TEX_UV] = stored_uvs + + _mdr.array = arrays + */ +} + +void MDRUVRectView::refresh() { + /* +clear() + + var rect : Rect2 = base_rect + edited_resource_current_size = rect.size + rect.position = rect.position * _rect_scale + rect.size = rect.size * _rect_scale + set_custom_minimum_size(rect.size) + + apply_zoom() + + refresh_rects() + */ +} +void MDRUVRectView::clear() { +} +void MDRUVRectView::refresh_rects() { + /* +clear_rects() + + if !_mdr: + return + + var partitions : Array = MeshDecompose.partition_mesh(_mdr) + + for p in partitions: + var s : Node = rect_editor_node_scene.instance() + + add_child(s) + s.set_editor_rect_scale(_rect_scale) + s.edited_resource_parent_size = edited_resource_current_size + s.set_edited_resource(_mdr, p) + + */ +} +void MDRUVRectView::clear_rects() { + /* +for c in get_children(): + c.queue_free() + remove_child(c) + */ +} + +void MDRUVRectView::_enter_tree() { + /* + + */ +} +void MDRUVRectView::_draw() { + /* +draw_rect(Rect2(Vector2(), get_size()), Color(0.2, 0.2, 0.2, 1)) + + if _background_texture: + draw_texture_rect_region(_background_texture, Rect2(Vector2(), get_size()), Rect2(Vector2(), _background_texture.get_size())) + */ +} + +void MDRUVRectView::on_mirror_horizontal_button_pressed() { + /* + if selected_rect && is_instance_valid(selected_rect) { + selected_rect.mirror_horizontal(); + }*/ +} +void MDRUVRectView::on_mirror_vertical_button_pressed() { + /* + if selected_rect && is_instance_valid(selected_rect): + selected_rect.mirror_vertical() + */ +} +void MDRUVRectView::on_rotate_left_button_button_pressed() { + /* + if selected_rect && is_instance_valid(selected_rect): + selected_rect.rotate_uvs(-rotation_amount) + */ +} + +void MDRUVRectView::on_rotate_amount_spinbox_changed(float val) { + /* + rotation_amount = val +*/ +} +void MDRUVRectView::on_rotate_right_button_button_pressed() { + /* + if selected_rect && is_instance_valid(selected_rect): + selected_rect.rotate_uvs(rotation_amount) +*/ +} +void MDRUVRectView::on_edited_resource_changed() { + /* + call_deferred("refresh") +*/ +} + +void MDRUVRectView::on_zoom_changed(float zoom) { + /* + _rect_scale = zoom + apply_zoom() +*/ +} + +void MDRUVRectView::on_visibility_changed() { + /* + if is_visible_in_tree(): + store_uvs() + call_deferred("refresh") +*/ +} + +void MDRUVRectView::ok_pressed() { + /* + _undo_redo.create_action("UV Editor Accept") + _undo_redo.add_do_method(self, "apply_uvs", _mdr, get_uvs(_mdr)) + _undo_redo.add_undo_method(self, "apply_uvs", _mdr, _stored_uvs) + _undo_redo.commit_action() +*/ +} +void MDRUVRectView::cancel_pressed() { + /* + if !_mdr: + return + + var arrays : Array = _mdr.get_array() + + if arrays.size() != ArrayMesh.ARRAY_MAX: + return + + # Make sure it gets copied + var uvs : PoolVector2Array = PoolVector2Array() + uvs.append_array(_stored_uvs) + + _undo_redo.create_action("UV Editor Cancel") + _undo_redo.add_do_method(self, "apply_uvs", _mdr, uvs) + _undo_redo.add_undo_method(self, "apply_uvs", _mdr, get_uvs(_mdr)) + _undo_redo.commit_action() + + _stored_uvs.resize(0) +*/ +} + +void MDRUVRectView::apply_zoom() { + /* + var rect : Rect2 = base_rect + edited_resource_current_size = rect.size + rect.position = rect.position * _rect_scale + rect.size = rect.size * _rect_scale + set_custom_minimum_size(rect.size) + + var p : MarginContainer = get_parent() as MarginContainer + + p.add_constant_override("margin_left", min(rect.size.x / 4.0, 50 * _rect_scale)) + p.add_constant_override("margin_right", min(rect.size.x / 4.0, 50 * _rect_scale)) + p.add_constant_override("margin_top", min(rect.size.y / 4.0, 50 * _rect_scale)) + p.add_constant_override("margin_bottom", min(rect.size.y / 4.0, 50 * _rect_scale)) + + for c in get_children(): + c.set_editor_rect_scale(_rect_scale) +*/ +} + +MDRUVRectView::MDRUVRectView() { + float _rect_scale = 1; + + Rect2 base_rect = Rect2(0, 0, 600, 600); + + PoolVector2Array _stored_uvs; + + EditorPlugin *_plugin = nullptr; + UndoRedo *_undo_redo = nullptr; + + Control *selected_rect = nullptr; + + rotation_amount = 45; + + /* var zoom_widget : Node = get_node_or_null(zoom_widget_path) + + if zoom_widget && !zoom_widget.is_connected("zoom_changed", self, "on_zoom_changed"): + zoom_widget.connect("zoom_changed", self, "on_zoom_changed") + + var mirror_horizontal_button : Button = get_node_or_null(mirror_horizontal_button_path) + if mirror_horizontal_button && !mirror_horizontal_button.is_connected("pressed", self, "on_mirror_horizontal_button_pressed"): + mirror_horizontal_button.connect("pressed", self, "on_mirror_horizontal_button_pressed") + + var mirror_vertical_button : Button = get_node_or_null(mirror_vertical_button_path) + if mirror_vertical_button && !mirror_vertical_button.is_connected("pressed", self, "on_mirror_vertical_button_pressed"): + mirror_vertical_button.connect("pressed", self, "on_mirror_vertical_button_pressed") + + var rotate_left_button : Button = get_node_or_null(rotate_left_button_path) + if rotate_left_button && !rotate_left_button.is_connected("pressed", self, "on_rotate_left_button_button_pressed"): + rotate_left_button.connect("pressed", self, "on_rotate_left_button_button_pressed") + + var rotate_amount_spinbox : SpinBox = get_node_or_null(rotate_amount_spinbox_path) + if rotate_amount_spinbox: + rotation_amount = rotate_amount_spinbox.value + if !rotate_amount_spinbox.is_connected("value_changed", self, "on_rotate_amount_spinbox_changed"): + rotate_amount_spinbox.connect("value_changed", self, "on_rotate_amount_spinbox_changed") + + var rotate_right_button : Button = get_node_or_null(rotate_right_button_path) + if rotate_right_button && !rotate_right_button.is_connected("pressed", self, "on_rotate_right_button_button_pressed"): + rotate_right_button.connect("pressed", self, "on_rotate_right_button_button_pressed") + + if !is_connected("visibility_changed", self, "on_visibility_changed"): + connect("visibility_changed", self, "on_visibility_changed") + +*/ +} + +MDRUVRectView::~MDRUVRectView() { +} + +void MDRUVRectView::_bind_methods() { +} diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.h b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.h new file mode 100644 index 000000000..d7d81d592 --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.h @@ -0,0 +1,112 @@ +#ifndef MDR_UV_RECT_VIEW_H +#define MDR_UV_RECT_VIEW_H + +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "core/math/rect2.h" +#include "core/pool_vector.h" +#include "core/reference.h" +#include "scene/gui/control.h" + +class MeshDataResource; +class MeshDataInstance; +class Texture; +class EditorPlugin; +class UndoRedo; +class Button; +class EditorZoomWidget; +class SpinBox; + +class MDRUVRectView : public Control { + GDCLASS(MDRUVRectView, Control); + +public: + void set_plugin(EditorPlugin *plugin); + void set_mesh_data_resource(Ref a); + void set_mesh_data_instance(MeshDataInstance *a); + void set_selected(Control *node); + + void store_uvs(); + PoolVector2Array get_uvs(Ref mdr); + void apply_uvs(Ref mdr, PoolVector2Array stored_uvs); + + void refresh(); + void clear(); + void refresh_rects(); + void clear_rects(); + + void _enter_tree(); + void _draw(); + + void on_mirror_horizontal_button_pressed(); + void on_mirror_vertical_button_pressed(); + void on_rotate_left_button_button_pressed(); + + void on_rotate_amount_spinbox_changed(float val); + void on_rotate_right_button_button_pressed(); + void on_edited_resource_changed(); + + void on_zoom_changed(float zoom); + + void on_visibility_changed(); + + void ok_pressed(); + void cancel_pressed(); + + void apply_zoom(); + + MDRUVRectView(); + ~MDRUVRectView(); + +protected: + static void _bind_methods(); + + EditorZoomWidget *zoom_widget; + + Button *mirror_horizontal_button; + Button *mirror_vertical_button; + + Button *rotate_left_button; + SpinBox *rotate_amount_spinbox; + Button *rotate_right_button; + +public: + float _rect_scale; + + Ref _mdr; + Ref _background_texture; + + Rect2 base_rect; + Vector2 edited_resource_current_size; + + PoolVector2Array _stored_uvs; + + EditorPlugin *_plugin; + UndoRedo *_undo_redo; + + Control *selected_rect; + + float rotation_amount; +}; + +#endif diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_node.cpp b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_node.cpp new file mode 100644 index 000000000..f610838c3 --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_node.cpp @@ -0,0 +1,482 @@ +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "mdr_uv_rect_view_node.h" + +void MDRUVRectViewNode::set_edited_resource(Ref mdr, PoolIntArray indices) { + /* + _mdr = mdr + _indices = indices + _uvs.resize(0) + + var arrays : Array = _mdr.get_array() + + if arrays.size() != ArrayMesh.ARRAY_MAX: + return + + if arrays[ArrayMesh.ARRAY_TEX_UV] == null: + return + + # Make sure it gets copied + _uvs.append_array(arrays[ArrayMesh.ARRAY_TEX_UV]) + + set_up_base_rect() + + refresh() + */ +} + +void MDRUVRectViewNode::mirror_horizontal() { + /* + var pia : PoolIntArray = PoolIntArray() + for index in _indices: + var found : bool = false + + for i in pia: + if i == index: + found = true + break + + if found: + continue + + pia.append(index) + + var uv : Vector2 = _uvs[index] + uv.x = 1.0 - uv.x + _uvs.set(index, uv) + + apply_uv() + update() + */ +} +void MDRUVRectViewNode::mirror_vertical() { + /* + var pia : PoolIntArray = PoolIntArray() + for index in _indices: + var found : bool = false + + for i in pia: + if i == index: + found = true + break + + if found: + continue + + pia.append(index) + + var uv : Vector2 = _uvs[index] + uv.y = 1.0 - uv.y + _uvs.set(index, uv) + + apply_uv() + update() + */ +} +void MDRUVRectViewNode::rotate_uvs(float amount) { + /* + var t : Transform2D = Transform2D(deg2rad(amount), Vector2()) + + var pia : PoolIntArray = PoolIntArray() + for index in _indices: + var found : bool = false + + for i in pia: + if i == index: + found = true + break + + if found: + continue + + pia.append(index) + + var uv : Vector2 = _uvs[index] + uv = t.xform(uv) + _uvs.set(index, uv) + + + re_normalize_uvs() + apply_uv() + update() + */ +} + +void MDRUVRectViewNode::set_selected(bool val) { + /* + selected = val + update() + */ +} + +void MDRUVRectViewNode::set_editor_rect_scale(float rect_scale) { + /* + _rect_scale = rect_scale + + refresh() + */ +} +void MDRUVRectViewNode::set_up_base_rect() { + /* + _base_rect = Rect2() + + if !_mdr: + return + + if _uvs.size() == 0: + return + + var vmin : Vector2 = _uvs[_indices[0]] + var vmax : Vector2 = vmin + for i in range(1, _indices.size()): + var uv : Vector2 = _uvs[_indices[i]] + + if uv.x < vmin.x: + vmin.x = uv.x + + if uv.x > vmax.x: + vmax.x = uv.x + + if uv.y < vmin.y: + vmin.y = uv.y + + if uv.y > vmax.y: + vmax.y = uv.y + + _base_rect = Rect2(vmin.x, vmin.y, vmax.x - vmin.x, vmax.y - vmin.y) + _base_rect.position *= edited_resource_parent_size + _base_rect.size *= edited_resource_parent_size + + _uv_min = vmin + _uv_max = vmax + + normalize_uvs() + + */ +} + +void MDRUVRectViewNode::re_normalize_uvs() { + /* + if _uvs.size() == 0: + return + + var vmin : Vector2 = _uvs[_indices[0]] + var vmax : Vector2 = vmin + for i in range(1, _indices.size()): + var uv : Vector2 = _uvs[_indices[i]] + + if uv.x < vmin.x: + vmin.x = uv.x + + if uv.x > vmax.x: + vmax.x = uv.x + + if uv.y < vmin.y: + vmin.y = uv.y + + if uv.y > vmax.y: + vmax.y = uv.y + + var xmm : float = vmax.x - vmin.x + var ymm : float = vmax.y - vmin.y + + if xmm == 0: + xmm = 0.0000001 + + if ymm == 0: + ymm = 0.0000001 + + for i in range(_uvs.size()): + var uv : Vector2 = _uvs[i] + + uv.x -= vmin.x + uv.x /= xmm + + uv.y -= vmin.y + uv.y /= ymm + + _uvs[i] = uv + */ +} +void MDRUVRectViewNode::normalize_uvs() { + /* + var xmm : float = _uv_max.x - _uv_min.x + var ymm : float = _uv_max.y - _uv_min.y + + if xmm == 0: + xmm = 0.0000001 + + if ymm == 0: + ymm = 0.0000001 + + for i in range(_uvs.size()): + var uv : Vector2 = _uvs[i] + + uv.x -= _uv_min.x + uv.x /= xmm + + uv.y -= _uv_min.y + uv.y /= ymm + + _uvs[i] = uv + */ +} +void MDRUVRectViewNode::apply_uv() { + /* + if !_mdr: + return + + var rect : Rect2 = get_rect() + + #rect needs to be converted back + rect.position /= _rect_scale + rect.size /= _rect_scale + rect.position /= edited_resource_parent_size + rect.size /= edited_resource_parent_size + + var arrays : Array = _mdr.get_array() + + if arrays.size() != ArrayMesh.ARRAY_MAX: + return + + if arrays[ArrayMesh.ARRAY_TEX_UV] == null: + return + + var uvs : PoolVector2Array = arrays[ArrayMesh.ARRAY_TEX_UV] + + for index in _indices: + var uv : Vector2 = _uvs[index] + + uv = uv * rect.size + rect.position + + uvs[index] = uv + + _uv_min = rect.position + _uv_max = rect.position + rect.size + + _base_rect = get_rect() + + arrays[ArrayMesh.ARRAY_TEX_UV] = uvs + _mdr.array = arrays + + */ +} + +void MDRUVRectViewNode::refresh() { + /* + if !_mdr: + return + + var rect : Rect2 = _base_rect + rect.position *= _rect_scale + rect.size *= _rect_scale + + rect_position = rect.position + rect_size = rect.size + + update() + */ +} + +void MDRUVRectViewNode::_draw() { + /* + if selected: + draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_selected_color) + draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_selected_border_color, false, _editor_rect_border_size) + else: + draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_color) + draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_border_color, false, _editor_rect_border_size) + + if _mdr && _uvs.size() > 0: + var c : Color = _edited_resource_uv_mesh_color + + for i in range(0, len(_indices), 3): + draw_line(_uvs[_indices[i]] * get_size(), _uvs[_indices[i + 1]] * get_size(), c, 1, false) + draw_line(_uvs[_indices[i + 1]] * get_size(), _uvs[_indices[i + 2]] * get_size(), c, 1, false) + draw_line(_uvs[_indices[i + 2]] * get_size(), _uvs[_indices[i]] * get_size(), c, 1, false) + + */ +} + +//based on / ported from engine/scene/gui/dialogs.h and .cpp +void MDRUVRectViewNode::_gui_input(Ref p_event) { + /* + if (p_event is InputEventMouseButton) && (p_event.get_button_index() == BUTTON_LEFT): + var mb : InputEventMouseButton = p_event as InputEventMouseButton + + if (mb.is_pressed()): + get_parent().set_selected(self) + + # Begin a possible dragging operation. + drag_type = _drag_hit_test(Vector2(mb.get_position().x, mb.get_position().y)) + + if (drag_type != DragType.DRAG_NONE): + drag_offset = get_global_mouse_position() - get_position() + + drag_offset_far = get_position() + get_size() - get_global_mouse_position() + + elif (drag_type != DragType.DRAG_NONE && !mb.is_pressed()): + # End a dragging operation. + + apply_uv() + + drag_type = DragType.DRAG_NONE + + if p_event is InputEventMouseMotion: + var mm : InputEventMouseMotion = p_event as InputEventMouseMotion + + if (drag_type == DragType.DRAG_NONE): + # Update the cursor while moving along the borders. + var cursor = CURSOR_ARROW + + var preview_drag_type : int = _drag_hit_test(Vector2(mm.get_position().x, mm.get_position().y)) + + var top_left : int = DragType.DRAG_RESIZE_TOP + DragType.DRAG_RESIZE_LEFT + var bottom_right : int = DragType.DRAG_RESIZE_BOTTOM + DragType.DRAG_RESIZE_RIGHT + var top_right : int = DragType.DRAG_RESIZE_TOP + DragType.DRAG_RESIZE_RIGHT + var bottom_left : int = DragType.DRAG_RESIZE_BOTTOM + DragType.DRAG_RESIZE_LEFT + + match (preview_drag_type): + DragType.DRAG_RESIZE_TOP: + cursor = CURSOR_VSIZE + DragType.DRAG_RESIZE_BOTTOM: + cursor = CURSOR_VSIZE + DragType.DRAG_RESIZE_LEFT: + cursor = CURSOR_HSIZE + DragType.DRAG_RESIZE_RIGHT: + cursor = CURSOR_HSIZE + top_left: + cursor = CURSOR_FDIAGSIZE + bottom_right: + cursor = CURSOR_FDIAGSIZE + top_right: + cursor = CURSOR_BDIAGSIZE + bottom_left: + cursor = CURSOR_BDIAGSIZE + + if (get_cursor_shape() != cursor): + set_default_cursor_shape(cursor); + + else: + # Update while in a dragging operation. + var global_pos : Vector2 = get_global_mouse_position() + + var rect : Rect2 = get_rect() + var min_size : Vector2 = get_combined_minimum_size() + + if (drag_type == DragType.DRAG_MOVE): + rect.position = global_pos - drag_offset + else: + if (drag_type & DragType.DRAG_RESIZE_TOP): + var bottom : int = rect.position.y + rect.size.y + var max_y : int = bottom - min_size.y + rect.position.y = min(global_pos.y - drag_offset.y, max_y) + rect.size.y = bottom - rect.position.y + elif (drag_type & DragType.DRAG_RESIZE_BOTTOM): + rect.size.y = global_pos.y - rect.position.y + drag_offset_far.y + + if (drag_type & DragType.DRAG_RESIZE_LEFT): + var right : int = rect.position.x + rect.size.x + var max_x : int = right - min_size.x + rect.position.x = min(global_pos.x - drag_offset.x, max_x) + rect.size.x = right - rect.position.x + elif (drag_type & DragType.DRAG_RESIZE_RIGHT): + rect.size.x = global_pos.x - rect.position.x + drag_offset_far.x + + set_size(rect.size) + set_position(rect.position) + */ +} + +//based on / ported from engine/scene/gui/dialogs.h and .cpp +int MDRUVRectViewNode::_drag_hit_test(Vector2 pos) { + /* + var drag_type : int = DragType.DRAG_NONE + + var scaleborder_size : int = 5 #get_constant("scaleborder_size", "WindowDialog") + + var rect : Rect2 = get_rect() + + if (pos.y < (scaleborder_size)): + drag_type = DragType.DRAG_RESIZE_TOP + elif (pos.y >= (rect.size.y - scaleborder_size)): + drag_type = DragType.DRAG_RESIZE_BOTTOM + + if (pos.x < scaleborder_size): + drag_type |= DragType.DRAG_RESIZE_LEFT + elif (pos.x >= (rect.size.x - scaleborder_size)): + drag_type |= DragType.DRAG_RESIZE_RIGHT + + if (drag_type == DragType.DRAG_NONE): + drag_type = DragType.DRAG_MOVE + + return drag_type + */ +} + +//based on / ported from engine/scene/gui/dialogs.h and .cpp +void MDRUVRectViewNode::_notification(int p_what) { + /* + if (p_what == NOTIFICATION_MOUSE_EXIT): + # Reset the mouse cursor when leaving the resizable window border. + if (_mdr && !drag_type): + if (get_default_cursor_shape() != CURSOR_ARROW): + set_default_cursor_shape(CURSOR_ARROW) + */ +} + +MDRUVRectViewNode::MDRUVRectViewNode() { + selected = false; + _base_rect = Rect2(0, 0, 100, 100); + + _edited_resource_rect_border_color = Color(0.8, 0.8, 0.8, 0.5); + _edited_resource_rect_color = Color(0.5, 0.5, 0.5, 0.2); + _edited_resource_rect_selected_border_color = Color(0.9, 0.9, 0.9, 0.8); + _edited_resource_rect_selected_color = Color(0.5, 0.5, 0.5, 0.4); + _edited_resource_uv_mesh_color = Color(1, 1, 1, 1); + _editor_rect_border_size = 2; + _edited_resource_font_color = Color(0, 0, 0, 1); + + drag_type = 0; + _rect_scale = 1; + + /* + [gd_scene load_steps=2 format=2] + + [ext_resource path="res://addons/mesh_data_resource_editor/uv_editor/RectViewNode.gd" type="Script" id=1] + + [node name="RectViewNode" type="MarginContainer"] + margin_right = 1024.0 + margin_bottom = 600.0 + script = ExtResource( 1 ) + __meta__ = { + "_edit_use_anchors_": false + } + */ +} + +MDRUVRectViewNode::~MDRUVRectViewNode() { +} + +void MDRUVRectViewNode::_bind_methods() { +} diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_node.h b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_node.h new file mode 100644 index 000000000..b0b31e41d --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_node.h @@ -0,0 +1,105 @@ +#ifndef MDR_UV_RECT_VIEW_NODE_H +#define MDR_UV_RECT_VIEW_NODE_H + +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "core/color.h" +#include "core/math/rect2.h" +#include "core/pool_vector.h" +#include "core/reference.h" + +#include "scene/gui/margin_container.h" + +class MeshDataResource; + +class MDRUVRectViewNode : public MarginContainer { + GDCLASS(MDRUVRectViewNode, MarginContainer); + +public: + enum DragType { + DRAG_NONE = 0, + DRAG_MOVE = 1, + DRAG_RESIZE_TOP = 1 << 1, + DRAG_RESIZE_RIGHT = 1 << 2, + DRAG_RESIZE_BOTTOM = 1 << 3, + DRAG_RESIZE_LEFT = 1 << 4 + }; + + void set_edited_resource(Ref mdr, PoolIntArray indices); + + void mirror_horizontal(); + void mirror_vertical(); + void rotate_uvs(float amount); + + void set_selected(bool val); + + void set_editor_rect_scale(float rect_scale); + void set_up_base_rect(); + + void re_normalize_uvs(); + void normalize_uvs(); + void apply_uv(); + + void refresh(); + + void _draw(); + void _gui_input(Ref p_event); + int _drag_hit_test(Vector2 pos); + + MDRUVRectViewNode(); + ~MDRUVRectViewNode(); + +protected: + + void _notification(int p_what); + static void _bind_methods(); + +public: + bool selected; + + Ref _mdr; + PoolIntArray _indices; + PoolVector2Array _uvs; + Rect2 _base_rect; + Vector2 _uv_min; + Vector2 _uv_max; + + Vector2 edited_resource_parent_size; + + Color _edited_resource_rect_border_color; + Color _edited_resource_rect_color; + Color _edited_resource_rect_selected_border_color; + Color _edited_resource_rect_selected_color; + Color _edited_resource_uv_mesh_color; + int _editor_rect_border_size; + Color _edited_resource_font_color; + String _editor_additional_text; + + int drag_type; + Vector2 drag_offset; + Vector2 drag_offset_far; + + float _rect_scale; +}; + +#endif diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_popup.cpp b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_popup.cpp new file mode 100644 index 000000000..da357200e --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_popup.cpp @@ -0,0 +1,51 @@ +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "mdr_uv_rect_view_popup.h" + +void MDRUVRectViewPopup::on_ok_pressed() { + //$UVEditor.ok_pressed() +} +void MDRUVRectViewPopup::on_cancel_pressed() { + //$UVEditor.cancel_pressed() +} + +void MDRUVRectViewPopup::_notification(int p_what) { + /* + func _enter_tree(): + if !is_connected("confirmed", self, "on_ok_pressed"): + connect("confirmed", self, "on_ok_pressed") + + if !get_cancel().is_connected("pressed", self, "on_cancel_pressed"): + get_cancel().connect("pressed", self, "on_cancel_pressed") + + */ +} + +MDRUVRectViewPopup::MDRUVRectViewPopup() { +} + +MDRUVRectViewPopup::~MDRUVRectViewPopup() { +} + +void MDRUVRectViewPopup::_bind_methods() { +} diff --git a/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_popup.h b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_popup.h new file mode 100644 index 000000000..8a7af8e84 --- /dev/null +++ b/modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view_popup.h @@ -0,0 +1,43 @@ +#ifndef MDR_UV_RECT_VIEW_POPUP_H +#define MDR_UV_RECT_VIEW_POPUP_H + +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "scene/gui/dialogs.h" + +class MDRUVRectViewPopup : public ConfirmationDialog { + GDCLASS(MDRUVRectViewPopup, ConfirmationDialog); + +public: + void on_ok_pressed(); + void on_cancel_pressed(); + + MDRUVRectViewPopup(); + ~MDRUVRectViewPopup(); + +protected: + void _notification(int p_what); + static void _bind_methods(); +}; + +#endif