mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-30 21:09:19 +01:00
Added skeleton classes for mesh data resource editor's uv rect editor.
This commit is contained in:
parent
2093cef963
commit
200b4b0405
@ -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
|
|
||||||
|
|
@ -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 )
|
|
@ -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()
|
|
@ -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<MeshDataResource> 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);
|
||||||
|
}
|
@ -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<MeshDataResource> a);
|
||||||
|
void set_mesh_data_instance(MeshDataInstance *a);
|
||||||
|
void ok_pressed();
|
||||||
|
void cancel_pressed();
|
||||||
|
|
||||||
|
MDRUVRectEditor();
|
||||||
|
~MDRUVRectEditor();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
324
modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.cpp
Normal file
324
modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.cpp
Normal file
@ -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<MeshDataResource> 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<MeshDataResource> 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<MeshDataResource> 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() {
|
||||||
|
}
|
112
modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.h
Normal file
112
modules/mesh_data_resource/editor/uv_editor/mdr_uv_rect_view.h
Normal file
@ -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<MeshDataResource> a);
|
||||||
|
void set_mesh_data_instance(MeshDataInstance *a);
|
||||||
|
void set_selected(Control *node);
|
||||||
|
|
||||||
|
void store_uvs();
|
||||||
|
PoolVector2Array get_uvs(Ref<MeshDataResource> mdr);
|
||||||
|
void apply_uvs(Ref<MeshDataResource> 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<MeshDataResource> _mdr;
|
||||||
|
Ref<Texture> _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
|
@ -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<MeshDataResource> 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<InputEvent> 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() {
|
||||||
|
}
|
@ -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<MeshDataResource> 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<InputEvent> p_event);
|
||||||
|
int _drag_hit_test(Vector2 pos);
|
||||||
|
|
||||||
|
MDRUVRectViewNode();
|
||||||
|
~MDRUVRectViewNode();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void _notification(int p_what);
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool selected;
|
||||||
|
|
||||||
|
Ref<MeshDataResource> _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
|
@ -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() {
|
||||||
|
}
|
@ -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
|
Loading…
Reference in New Issue
Block a user