Initial skeleton conversion of mdr_ed_mesh_utils.

This commit is contained in:
Relintai 2022-04-11 02:35:31 +02:00
parent 200b4b0405
commit d3118e1d4b
10 changed files with 856 additions and 1363 deletions

View File

@ -1,18 +0,0 @@
tool
extends PanelContainer
func set_plugin(plugin : EditorPlugin) -> void:
$ScrollContainer/MarginContainer/RectView.set_plugin(plugin)
func set_mesh_data_resource(a : MeshDataResource) -> void:
$ScrollContainer/MarginContainer/RectView.set_mesh_data_resource(a)
func set_mesh_data_instance(a : MeshDataInstance) -> void:
$ScrollContainer/MarginContainer/RectView.set_mesh_data_instance(a)
func ok_pressed() -> void:
$ScrollContainer/MarginContainer/RectView.ok_pressed()
func cancel_pressed() -> void:
$ScrollContainer/MarginContainer/RectView.cancel_pressed()

View File

@ -1,250 +0,0 @@
tool
extends Control
var MeshDecompose = preload("res://addons/mesh_data_resource_editor/utilities/mesh_decompose.gd")
var rect_editor_node_scene : PackedScene = preload("res://addons/mesh_data_resource_editor/uv_editor/RectViewNode.tscn")
export(NodePath) var zoom_widget_path : NodePath = ""
export(NodePath) var mirror_horizontal_button_path : NodePath = ""
export(NodePath) var mirror_vertical_button_path : NodePath = ""
export(NodePath) var rotate_left_button_path : NodePath = ""
export(NodePath) var rotate_amount_spinbox_path : NodePath = ""
export(NodePath) var rotate_right_button_path : NodePath = ""
var _rect_scale : float = 1
var _mdr : MeshDataResource = null
var _background_texture : Texture = null
var base_rect : Rect2 = Rect2(0, 0, 600, 600)
var edited_resource_current_size : Vector2 = Vector2()
var _stored_uvs : PoolVector2Array = PoolVector2Array()
var _plugin : EditorPlugin = null
var _undo_redo : UndoRedo = null
var selected_rect : Control = null
var rotation_amount : float = 45
func _enter_tree():
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")
func on_mirror_horizontal_button_pressed() -> void:
if selected_rect && is_instance_valid(selected_rect):
selected_rect.mirror_horizontal()
func on_mirror_vertical_button_pressed() -> void:
if selected_rect && is_instance_valid(selected_rect):
selected_rect.mirror_vertical()
func on_rotate_left_button_button_pressed() -> void:
if selected_rect && is_instance_valid(selected_rect):
selected_rect.rotate_uvs(-rotation_amount)
func on_rotate_amount_spinbox_changed(val : float) -> void:
rotation_amount = val
func on_rotate_right_button_button_pressed() -> void:
if selected_rect && is_instance_valid(selected_rect):
selected_rect.rotate_uvs(rotation_amount)
func set_plugin(plugin : EditorPlugin) -> void:
_plugin = plugin
_undo_redo = _plugin.get_undo_redo()
func on_visibility_changed() -> void:
if is_visible_in_tree():
store_uvs()
call_deferred("refresh")
func apply_zoom() -> void:
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)
func on_zoom_changed(zoom : float) -> void:
_rect_scale = zoom
apply_zoom()
func _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()))
func refresh() -> void:
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()
func clear() -> void:
pass
func refresh_rects() -> void:
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)
func clear_rects():
for c in get_children():
c.queue_free()
remove_child(c)
func set_mesh_data_resource(a : MeshDataResource) -> void:
_mdr = a
func set_mesh_data_instance(a : MeshDataInstance) -> void:
_background_texture = null
if a:
_background_texture = a.texture
func on_edited_resource_changed() -> void:
call_deferred("refresh")
func get_uvs(mdr : MeshDataResource) -> PoolVector2Array:
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]
func store_uvs() -> void:
_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])
func apply_uvs(mdr : MeshDataResource, stored_uvs : PoolVector2Array) -> void:
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
func ok_pressed() -> void:
_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()
func cancel_pressed() -> void:
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)
func set_selected(node : Control) -> void:
if selected_rect && is_instance_valid(selected_rect):
selected_rect.set_selected(false)
selected_rect = node
if selected_rect:
selected_rect.set_selected(true)

View File

@ -1,418 +0,0 @@
tool
extends MarginContainer
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
};
var selected : bool = false
var _mdr : MeshDataResource = null
var _indices : PoolIntArray = PoolIntArray()
var _uvs : PoolVector2Array = PoolVector2Array()
var _base_rect : Rect2 = Rect2(0, 0, 100, 100)
var _uv_min : Vector2 = Vector2()
var _uv_max : Vector2 = Vector2()
var edited_resource_parent_size : Vector2 = Vector2()
var _edited_resource_rect_border_color : Color = Color(0.8, 0.8, 0.8, 0.5)
var _edited_resource_rect_color : Color = Color(0.5, 0.5, 0.5, 0.2)
var _edited_resource_rect_selected_border_color : Color = Color(0.9, 0.9, 0.9, 0.8)
var _edited_resource_rect_selected_color : Color = Color(0.5, 0.5, 0.5, 0.4)
var _edited_resource_uv_mesh_color : Color = Color(1, 1, 1, 1)
var _editor_rect_border_size : int = 2
var _edited_resource_font_color : Color = Color(0, 0, 0, 1)
var _editor_additional_text : String = ""
var drag_type : int
var drag_offset : Vector2
var drag_offset_far : Vector2
var _rect_scale : float = 1
func _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)
func mirror_horizontal() -> void:
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()
func mirror_vertical() -> void:
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()
func rotate_uvs(amount : float) -> void:
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()
func refresh() -> void:
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()
func set_editor_rect_scale(rect_scale) -> void:
_rect_scale = rect_scale
refresh()
func set_edited_resource(mdr : MeshDataResource, indices : PoolIntArray):
_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()
func set_up_base_rect() -> void:
_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()
func re_normalize_uvs() -> void:
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
func normalize_uvs() -> void:
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
func apply_uv() -> void:
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
#based on / ported from engine/scene/gui/dialogs.h and .cpp
func _notification(p_what : int) -> void:
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)
#based on / ported from engine/scene/gui/dialogs.h and .cpp
func _gui_input(p_event : InputEvent) -> void:
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
func _drag_hit_test(pos : Vector2) -> int:
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
func set_selected(val : bool) -> void:
selected = val
update()

View File

@ -1,11 +0,0 @@
[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
}

View File

@ -1,121 +0,0 @@
[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 )

View File

@ -1,15 +0,0 @@
tool
extends ConfirmationDialog
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")
func on_ok_pressed() -> void:
$UVEditor.ok_pressed()
func on_cancel_pressed() -> void:
$UVEditor.cancel_pressed()

View File

@ -0,0 +1,153 @@
#ifndef MDR_ED_MESH_UTILS_H
#define MDR_ED_MESH_UTILS_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/ustring.h"
#include "core/pool_vector.h"
#include "core/math/vector3.h"
#include "core/reference.h"
#include "core/array.h"
class MeshDataResource;
class SurfaceTool;
class MDREDMeshUtils {
public:
struct SeamTriangleHelper {
int i0;
int i1;
int i2;
int orig_index;
int index_index;
int side_index_1;
int side_index_2;
bool side_index_1_cut;
bool side_index_2_cut;
bool processed;
int get_other_side_index(int index);
int get_side_index(int i);
int get_side_index_cut();
int get_opposite_side_index_cut();
bool is_side_index_cut(int i);
bool is_the_same(SeamTriangleHelper h);
bool is_triangle(int pi0, int pi1, int pi2);
bool is_neighbour_to(int index);
bool needs_to_be_cut_near(int index);
bool has_cut();
bool both_sides_need_cut();
void setup(int pi0, int pi1, int pi2, int porig_ind, int pindex_index, PoolIntArray seams);
void determine_cuts(PoolIntArray seams);
bool check_cut(int ind0, int ind1, PoolIntArray seams);
String _to_string();
SeamTriangleHelper();
};
static void remove_triangle(Ref<MeshDataResource> mdr, int triangle_index);
static bool add_triangulated_mesh_from_points_delaunay(Ref<MeshDataResource> mdr, PoolVector3Array selected_points, Vector3 last_known_camera_facing);
static void add_triangulated_mesh_from_points(Ref<MeshDataResource> mdr, PoolVector3Array selected_points, Vector3 last_known_camera_facing);
// Appends a triangle to the mesh. It's created from miroring v2 to the ev0, and ev1 edge
static void append_triangle_to_tri_edge(Ref<MeshDataResource> mdr, Vector3 ev0, Vector3 ev1, Vector3 v2);
static void add_triangle_at(Ref<MeshDataResource> mdr, Vector3 v0, Vector3 v1, Vector3 v2, bool flip = false);
static void add_triangle(Ref<MeshDataResource> mdr);
// Appends a quad to the mesh. It's created to the opposite side of v2 to the ev0, and ev1 edge
static void append_quad_to_tri_edge(Ref<MeshDataResource> mdr, Vector3 ev0, Vector3 ev1, Vector3 v2);
static void add_quad_at(Ref<MeshDataResource> mdr, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, bool flip = false);
static void add_quad(Ref<MeshDataResource> mdr);
static void add_box(Ref<MeshDataResource> mdr);
static void merge_in_surface_tool(Ref<MeshDataResource> mdr, Ref<SurfaceTool> st, bool generate_normals_if_needed = true, bool generate_tangents_if_needed = true);
static void merge_in_arrays(Ref<MeshDataResource> mdr, Array merge);
static Array get_arrays_prepared(Ref<MeshDataResource> mdr);
// There are probably better ways to do this
static bool should_flip_reflected_triangle(Vector3 v0, Vector3 v1, Vector3 v2);
static Vector3 reflect_vertex(Vector3 v0, Vector3 v1, Vector3 v2);
static Vector3 get_face_normal_arr_ti(PoolVector3Array verts, PoolIntArray indices, int triangle_index, bool flipped = false);
static Vector3 get_face_normal_arr(PoolVector3Array verts, PoolIntArray indices, int index, bool flipped = false);
static Vector3 get_face_normal(Vector3 v0, Vector3 v1, Vector3 v2, bool flipped = false);
static bool should_triangle_flip(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 similar_dir_normal);
static bool is_normal_similar(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 similar_dir_normal);
static bool is_direction_similar(Vector3 d0, Vector3 d1);
static void flip_triangle_ti(Ref<MeshDataResource> mdr, int triangle_index);
static void flip_triangle(Ref<MeshDataResource> mdr, int index);
static void add_into_surface_tool(Ref<MeshDataResource> mdr, Ref<SurfaceTool> st);
static Array generate_normals_arrs(Array arrays);
static void generate_normals_mdr(Ref<MeshDataResource> mdr);
// Apparently surfacetool adds more verts during normal generation
// Keeping this here for now
static void generate_normals_surface_tool(Ref<MeshDataResource> mdr);
static void generate_tangents(Ref<MeshDataResource> mdr);
static Array remove_used_vertices(Array arrays);
static Array remove_vertices(Array arrays, PoolIntArray indices);
static int find_max(PoolIntArray arr);
static int find_max_capped(PoolIntArray arr, int last);
static PoolIntArray order_seam_indices(PoolIntArray arr);
static void add_seam_not_ordered(Ref<MeshDataResource> mdr, int index0, int index1);
static void remove_seam_not_ordered(Ref<MeshDataResource> mdr, int index0, int index1);
static bool has_seam(Ref<MeshDataResource> mdr, int index0, int index1);
static void add_seam(Ref<MeshDataResource> mdr, int index0, int index1);
static void remove_seam(Ref<MeshDataResource> mdr, int index0, int index1);
static bool is_verts_equal(Vector3 v0, Vector3 v1);
static void points_to_seams(Ref<MeshDataResource> mdr, PoolVector3Array points);
static PoolVector3Array seams_to_points(Ref<MeshDataResource> mdr);
static bool is_matching_seam(int i0, int i1, int si0, int si1);
static bool pool_int_arr_contains(PoolIntArray arr, int val);
static void apply_seam(Ref<MeshDataResource> mdr);
static void apply_seam_old(Ref<MeshDataResource> mdr);
// This will not touch the indices!
static Array seam_apply_duplicate_vertices(Array arrays, PoolIntArray duplicate_verts_indices);
};
#endif