mirror of
https://github.com/Relintai/broken_seals.git
synced 2024-12-18 01:06:47 +01:00
Added the curve editor and polygon editor from Material Maker. I only fixed compile so far.
This commit is contained in:
parent
df1a1c59a2
commit
c082ee9a60
98
game/addons/mat_maker_gd/nodes/bases/curve_base.gd
Normal file
98
game/addons/mat_maker_gd/nodes/bases/curve_base.gd
Normal file
@ -0,0 +1,98 @@
|
||||
tool
|
||||
extends MMNode
|
||||
|
||||
class Point:
|
||||
var p : Vector2
|
||||
var ls : float
|
||||
var rs : float
|
||||
func _init(x : float, y : float, nls : float, nrs : float) -> void:
|
||||
p = Vector2(x, y)
|
||||
ls = nls
|
||||
rs = nrs
|
||||
|
||||
var points = [ Point.new(0.0, 0.0, 0.0, 1.0), Point.new(1.0, 1.0, 1.0, 0.0) ]
|
||||
|
||||
func to_string() -> String:
|
||||
var rv = PoolStringArray()
|
||||
for p in points:
|
||||
rv.append("("+str(p.x)+","+str(p.y)+","+str(p.ls)+","+str(p.rs)+")")
|
||||
return rv.join(",")
|
||||
|
||||
func clear() -> void:
|
||||
points.clear()
|
||||
|
||||
func add_point(x : float, y : float, ls : float = INF, rs : float = INF) -> void:
|
||||
for i in points.size():
|
||||
if x < points[i].p.x:
|
||||
if ls == INF:
|
||||
ls == 0
|
||||
if rs == INF:
|
||||
rs == 0
|
||||
points.insert(i, Point.new(x, y, ls, rs))
|
||||
return
|
||||
points.append(Point.new(x, y, ls, rs))
|
||||
|
||||
func remove_point(index : int) -> bool:
|
||||
if index <= 0 or index >= points.size() - 1:
|
||||
return false
|
||||
else:
|
||||
points.remove(index)
|
||||
return true
|
||||
|
||||
func get_point_count() -> int:
|
||||
return points.size()
|
||||
|
||||
func set_point(i : int, v : Point) -> void:
|
||||
points[i] = v
|
||||
|
||||
func get_shader_params(name) -> Dictionary:
|
||||
var rv = {}
|
||||
for i in range(points.size()):
|
||||
rv["p_"+name+"_"+str(i)+"_x"] = points[i].p.x
|
||||
rv["p_"+name+"_"+str(i)+"_y"] = points[i].p.y
|
||||
rv["p_"+name+"_"+str(i)+"_ls"] = points[i].ls
|
||||
rv["p_"+name+"_"+str(i)+"_rs"] = points[i].rs
|
||||
return rv
|
||||
|
||||
func get_shader(name) -> String:
|
||||
var shader
|
||||
shader = "float "+name+"_curve_fct(float x) {\n"
|
||||
for i in range(points.size()-1):
|
||||
if i < points.size()-2:
|
||||
shader += "if (x <= p_"+name+"_"+str(i+1)+"_x) "
|
||||
shader += "{\n"
|
||||
shader += "float dx = x - p_"+name+"_"+str(i)+"_x;\n"
|
||||
shader += "float d = p_"+name+"_"+str(i+1)+"_x - p_"+name+"_"+str(i)+"_x;\n"
|
||||
shader += "float t = dx/d;\n"
|
||||
shader += "float omt = (1.0 - t);\n"
|
||||
shader += "float omt2 = omt * omt;\n"
|
||||
shader += "float omt3 = omt2 * omt;\n"
|
||||
shader += "float t2 = t * t;\n"
|
||||
shader += "float t3 = t2 * t;\n"
|
||||
shader += "d /= 3.0;\n"
|
||||
shader += "float y1 = p_"+name+"_"+str(i)+"_y;\n"
|
||||
shader += "float yac = p_"+name+"_"+str(i)+"_y + d*p_"+name+"_"+str(i)+"_rs;\n"
|
||||
shader += "float ybc = p_"+name+"_"+str(i+1)+"_y - d*p_"+name+"_"+str(i+1)+"_ls;\n"
|
||||
shader += "float y2 = p_"+name+"_"+str(i+1)+"_y;\n"
|
||||
shader += "return y1*omt3 + yac*omt2*t*3.0 + ybc*omt*t2*3.0 + y2*t3;\n"
|
||||
shader += "}\n"
|
||||
shader += "}\n"
|
||||
return shader
|
||||
|
||||
func serialize() -> Dictionary:
|
||||
var rv = []
|
||||
for p in points:
|
||||
rv.append({ x=p.p.x, y=p.p.y, ls=p.ls, rs=p.rs })
|
||||
return { type="Curve", points=rv }
|
||||
|
||||
func deserialize(v) -> void:
|
||||
clear()
|
||||
if typeof(v) == TYPE_DICTIONARY and v.has("type") and v.type == "Curve":
|
||||
for p in v.points:
|
||||
add_point(p.x, p.y, p.ls, p.rs)
|
||||
elif typeof(v) == TYPE_OBJECT and v.get_script() == get_script():
|
||||
clear()
|
||||
for p in v.points:
|
||||
add_point(p.p.x, p.p.y, p.ls, p.rs)
|
||||
else:
|
||||
print("Cannot deserialize curve")
|
71
game/addons/mat_maker_gd/nodes/bases/polygon_base.gd
Normal file
71
game/addons/mat_maker_gd/nodes/bases/polygon_base.gd
Normal file
@ -0,0 +1,71 @@
|
||||
tool
|
||||
extends MMNode
|
||||
|
||||
var points : Array = [Vector2(0.2, 0.2), Vector2(0.7, 0.4), Vector2(0.4, 0.7)]
|
||||
|
||||
func to_string() -> String:
|
||||
var rv = PoolStringArray()
|
||||
for p in points:
|
||||
rv.append("("+str(p.x)+","+str(p.y)+")")
|
||||
return rv.join(",")
|
||||
|
||||
func clear() -> void:
|
||||
points.clear()
|
||||
|
||||
func add_point(x : float, y : float, closed : bool = true) -> void:
|
||||
var p : Vector2 = Vector2(x, y)
|
||||
var points_count = points.size()
|
||||
if points_count < 3:
|
||||
points.append(p)
|
||||
return
|
||||
var min_length : float = (p-Geometry.get_closest_point_to_segment_2d(p, points[0], points[points_count-1])).length()
|
||||
var insert_point = 0
|
||||
for i in points_count-1:
|
||||
var length = (p-Geometry.get_closest_point_to_segment_2d(p, points[i], points[i+1])).length()
|
||||
if length < min_length:
|
||||
min_length = length
|
||||
insert_point = i+1
|
||||
if !closed and insert_point == 0 and (points[0]-p).length() > (points[points_count-1]-p).length():
|
||||
insert_point = points_count
|
||||
points.insert(insert_point, p)
|
||||
|
||||
func remove_point(index : int) -> bool:
|
||||
var s = points.size()
|
||||
if s < 4 or index < 0 or index >= s:
|
||||
return false
|
||||
else:
|
||||
points.remove(index)
|
||||
return true
|
||||
|
||||
func get_point_count() -> int:
|
||||
return points.size()
|
||||
|
||||
func get_point(i : int) -> Vector2:
|
||||
return points[i]
|
||||
|
||||
func set_point(i : int, v : Vector2) -> void:
|
||||
points[i] = v
|
||||
|
||||
func get_shader() -> String:
|
||||
var elements : PoolStringArray = PoolStringArray()
|
||||
for p in points:
|
||||
elements.append("vec2(%.9f, %.9f)" % [p.x, p.y])
|
||||
return "{"+elements.join(", ")+"}"
|
||||
|
||||
func serialize() -> Dictionary:
|
||||
var rv = []
|
||||
for p in points:
|
||||
rv.append({ x=p.x, y=p.y })
|
||||
return { type="Polygon", points=rv }
|
||||
|
||||
func deserialize(v) -> void:
|
||||
clear()
|
||||
if typeof(v) == TYPE_DICTIONARY and v.has("type") and v.type == "Polygon":
|
||||
for p in v.points:
|
||||
points.push_back(Vector2(p.x, p.y))
|
||||
elif typeof(v) == TYPE_OBJECT and v.get_script() == get_script():
|
||||
clear()
|
||||
for p in v.points:
|
||||
points.push_back(Vector2(p.x, p.y))
|
||||
else:
|
||||
print("Cannot deserialize polygon")
|
66
game/addons/mat_maker_gd/widgets/curve_edit/control_point.gd
Normal file
66
game/addons/mat_maker_gd/widgets/curve_edit/control_point.gd
Normal file
@ -0,0 +1,66 @@
|
||||
extends Control
|
||||
|
||||
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
|
||||
|
||||
var moving : bool = false
|
||||
|
||||
var min_x : float
|
||||
var max_x : float
|
||||
var min_y : float
|
||||
var max_y : float
|
||||
|
||||
const OFFSET : Vector2 = Vector2(3, 3)
|
||||
|
||||
signal moved(index)
|
||||
signal removed(index)
|
||||
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _draw():
|
||||
var current_theme : Theme = get_node("/root/MainWindow").theme
|
||||
var color : Color = current_theme.get_color("font_color", "Label")
|
||||
for c in get_children():
|
||||
if c.visible:
|
||||
draw_line(OFFSET, c.rect_position+OFFSET, color)
|
||||
draw_rect(Rect2(0, 0, 7, 7), color)
|
||||
|
||||
#p : MMCurve.Point
|
||||
func initialize(p) -> void:
|
||||
rect_position = get_parent().transform_point(p.p)-OFFSET
|
||||
if p.ls != INF:
|
||||
$LeftSlope.rect_position = $LeftSlope.distance*(get_parent().rect_size*Vector2(1.0, -p.ls)).normalized()
|
||||
if p.rs != INF:
|
||||
$RightSlope.rect_position = $RightSlope.distance*(get_parent().rect_size*Vector2(1.0, -p.rs)).normalized()
|
||||
|
||||
func set_constraint(x : float, X : float, y : float, Y : float) -> void:
|
||||
min_x = x
|
||||
max_x = X
|
||||
min_y = y
|
||||
max_y = Y
|
||||
|
||||
func _on_ControlPoint_gui_input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
moving = true
|
||||
else:
|
||||
moving = false
|
||||
get_parent().update_controls()
|
||||
elif event.button_index == BUTTON_RIGHT and event.pressed:
|
||||
emit_signal("removed", get_index())
|
||||
elif moving and event is InputEventMouseMotion:
|
||||
rect_position += event.relative
|
||||
if rect_position.x < min_x:
|
||||
rect_position.x = min_x
|
||||
elif rect_position.x > max_x:
|
||||
rect_position.x = max_x
|
||||
if rect_position.y < min_y:
|
||||
rect_position.y = min_y
|
||||
elif rect_position.y > max_y:
|
||||
rect_position.y = max_y
|
||||
emit_signal("moved", get_index())
|
||||
|
||||
func update_tangents() -> void:
|
||||
update()
|
||||
emit_signal("moved", get_index())
|
@ -0,0 +1,39 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/slope_point.gd" type="Script" id=1]
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/control_point.gd" type="Script" id=2]
|
||||
|
||||
[node name="ControlPoint" type="Control"]
|
||||
margin_left = 56.9864
|
||||
margin_top = 33.8615
|
||||
margin_right = 63.9864
|
||||
margin_bottom = 40.8615
|
||||
rect_min_size = Vector2( 7, 7 )
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="LeftSlope" type="Control" parent="."]
|
||||
margin_left = -18.5235
|
||||
margin_right = -11.5235
|
||||
margin_bottom = 7.0
|
||||
rect_min_size = Vector2( 7, 7 )
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
distance = -30.0
|
||||
|
||||
[node name="RightSlope" type="Control" parent="."]
|
||||
margin_left = 15.6919
|
||||
margin_right = 22.6919
|
||||
margin_bottom = 7.0
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
distance = 30.0
|
||||
[connection signal="gui_input" from="." to="." method="_on_ControlPoint_gui_input"]
|
||||
[connection signal="gui_input" from="LeftSlope" to="LeftSlope" method="_on_ControlPoint_gui_input"]
|
||||
[connection signal="gui_input" from="RightSlope" to="RightSlope" method="_on_ControlPoint_gui_input"]
|
32
game/addons/mat_maker_gd/widgets/curve_edit/curve_dialog.gd
Normal file
32
game/addons/mat_maker_gd/widgets/curve_edit/curve_dialog.gd
Normal file
@ -0,0 +1,32 @@
|
||||
extends WindowDialog
|
||||
|
||||
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
|
||||
|
||||
var previous_value
|
||||
|
||||
signal curve_changed(curve)
|
||||
signal return_curve(curve)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _on_CurveDialog_popup_hide():
|
||||
emit_signal("return_curve", null)
|
||||
|
||||
func _on_OK_pressed():
|
||||
emit_signal("return_curve", $VBoxContainer/EditorContainer/CurveEditor.curve)
|
||||
|
||||
func _on_Cancel_pressed():
|
||||
emit_signal("return_curve", previous_value)
|
||||
|
||||
func edit_curve(curve) -> Array:
|
||||
previous_value = curve.duplicate()
|
||||
$VBoxContainer/EditorContainer/CurveEditor.set_curve(curve)
|
||||
popup_centered()
|
||||
var result = yield(self, "return_curve")
|
||||
queue_free()
|
||||
return result
|
||||
|
||||
func _on_CurveEditor_value_changed(value):
|
||||
emit_signal("curve_changed", value)
|
@ -0,0 +1,81 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_editor.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_dialog.gd" type="Script" id=2]
|
||||
|
||||
[node name="CurveDialog" type="WindowDialog"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 307.0
|
||||
margin_top = 151.0
|
||||
margin_right = -347.0
|
||||
margin_bottom = -174.0
|
||||
window_title = "Edit curve"
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 5.0
|
||||
margin_top = 5.0
|
||||
margin_right = -5.0
|
||||
margin_bottom = -5.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="EditorContainer" type="MarginContainer" parent="VBoxContainer"]
|
||||
margin_right = 616.0
|
||||
margin_bottom = 353.0
|
||||
rect_clip_content = true
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/margin_right = 4
|
||||
custom_constants/margin_top = 4
|
||||
custom_constants/margin_left = 4
|
||||
custom_constants/margin_bottom = 4
|
||||
|
||||
[node name="CurveEditor" parent="VBoxContainer/EditorContainer" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 4.0
|
||||
margin_top = 4.0
|
||||
margin_right = 612.0
|
||||
margin_bottom = 349.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="VBoxContainer"]
|
||||
margin_top = 357.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 361.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
margin_top = 365.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 385.0
|
||||
|
||||
[node name="Control" type="Control" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_right = 488.0
|
||||
margin_bottom = 20.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="OK" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_left = 492.0
|
||||
margin_right = 552.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 60, 0 )
|
||||
text = "OK"
|
||||
|
||||
[node name="Cancel" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_left = 556.0
|
||||
margin_right = 616.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 60, 0 )
|
||||
text = "Cancel"
|
||||
[connection signal="popup_hide" from="." to="." method="_on_CurveDialog_popup_hide"]
|
||||
[connection signal="value_changed" from="VBoxContainer/EditorContainer/CurveEditor" to="." method="_on_CurveEditor_value_changed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/OK" to="." method="_on_OK_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/Cancel" to="." method="_on_Cancel_pressed"]
|
32
game/addons/mat_maker_gd/widgets/curve_edit/curve_edit.gd
Normal file
32
game/addons/mat_maker_gd/widgets/curve_edit/curve_edit.gd
Normal file
@ -0,0 +1,32 @@
|
||||
extends Control
|
||||
|
||||
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
|
||||
|
||||
var value = null setget set_value
|
||||
|
||||
|
||||
signal updated(curve)
|
||||
|
||||
|
||||
func _ready():
|
||||
set_value(MMCurve.new())
|
||||
|
||||
func set_value(v) -> void:
|
||||
value = v.duplicate()
|
||||
$CurveView.curve = value
|
||||
$CurveView.update()
|
||||
|
||||
func _on_CurveEdit_pressed():
|
||||
var dialog = preload("res://addons/mat_maker_gd/widgets/curve_edit/curve_dialog.tscn").instance()
|
||||
add_child(dialog)
|
||||
dialog.connect("curve_changed", self, "on_value_changed")
|
||||
var new_curve = dialog.edit_curve(value)
|
||||
while new_curve is GDScriptFunctionState:
|
||||
new_curve = yield(new_curve, "completed")
|
||||
if new_curve != null:
|
||||
set_value(new_curve)
|
||||
emit_signal("updated", new_curve.duplicate())
|
||||
|
||||
func on_value_changed(v) -> void:
|
||||
set_value(v)
|
||||
emit_signal("updated", v.duplicate())
|
21
game/addons/mat_maker_gd/widgets/curve_edit/curve_edit.tscn
Normal file
21
game/addons/mat_maker_gd/widgets/curve_edit/curve_edit.tscn
Normal file
@ -0,0 +1,21 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_edit.gd" type="Script" id=1]
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="CurveEdit" type="Button"]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -1280.0
|
||||
margin_right = -1220.0
|
||||
margin_bottom = -700.0
|
||||
rect_min_size = Vector2( 60, 20 )
|
||||
focus_mode = 1
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="CurveView" parent="." instance=ExtResource( 2 )]
|
||||
[connection signal="pressed" from="." to="." method="_on_CurveEdit_pressed"]
|
64
game/addons/mat_maker_gd/widgets/curve_edit/curve_editor.gd
Normal file
64
game/addons/mat_maker_gd/widgets/curve_edit/curve_editor.gd
Normal file
@ -0,0 +1,64 @@
|
||||
extends "res://addons/mat_maker_gd/widgets/curve_edit/curve_view.gd"
|
||||
|
||||
signal value_changed(value)
|
||||
|
||||
func _ready():
|
||||
update_controls()
|
||||
|
||||
func set_curve(c) -> void:
|
||||
curve = c
|
||||
update()
|
||||
update_controls()
|
||||
|
||||
func update_controls() -> void:
|
||||
for c in get_children():
|
||||
c.queue_free()
|
||||
for i in curve.points.size():
|
||||
var p = curve.points[i]
|
||||
var control_point = preload("res://addons/mat_maker_gd/widgets/curve_edit/control_point.tscn").instance()
|
||||
add_child(control_point)
|
||||
control_point.initialize(p)
|
||||
control_point.rect_position = transform_point(p.p)-control_point.OFFSET
|
||||
if i == 0 or i == curve.points.size()-1:
|
||||
control_point.set_constraint(control_point.rect_position.x, control_point.rect_position.x, -control_point.OFFSET.y, rect_size.y-control_point.OFFSET.y)
|
||||
if i == 0:
|
||||
control_point.get_child(0).visible = false
|
||||
else:
|
||||
control_point.get_child(1).visible = false
|
||||
else:
|
||||
var min_x = transform_point(curve.points[i-1].p).x+1
|
||||
var max_x = transform_point(curve.points[i+1].p).x-1
|
||||
control_point.set_constraint(min_x, max_x, -control_point.OFFSET.y, rect_size.y-control_point.OFFSET.y)
|
||||
control_point.connect("moved", self, "_on_ControlPoint_moved")
|
||||
control_point.connect("removed", self, "_on_ControlPoint_removed")
|
||||
emit_signal("value_changed", curve)
|
||||
|
||||
func _on_ControlPoint_moved(index):
|
||||
var control_point = get_child(index)
|
||||
curve.points[index].p = reverse_transform_point(control_point.rect_position+control_point.OFFSET)
|
||||
if control_point.has_node("LeftSlope"):
|
||||
var slope_vector = control_point.get_node("LeftSlope").rect_position/rect_size
|
||||
if slope_vector.x != 0:
|
||||
curve.points[index].ls = -slope_vector.y / slope_vector.x
|
||||
if control_point.has_node("RightSlope"):
|
||||
var slope_vector = control_point.get_node("RightSlope").rect_position/rect_size
|
||||
if slope_vector.x != 0:
|
||||
curve.points[index].rs = -slope_vector.y / slope_vector.x
|
||||
update()
|
||||
emit_signal("value_changed", curve)
|
||||
|
||||
func _on_ControlPoint_removed(index):
|
||||
if curve.remove_point(index):
|
||||
update()
|
||||
update_controls()
|
||||
|
||||
func _on_CurveEditor_gui_input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT and event.doubleclick:
|
||||
var new_point_position = reverse_transform_point(get_local_mouse_position())
|
||||
curve.add_point(new_point_position.x, new_point_position.y, 0.0, 0.0)
|
||||
update_controls()
|
||||
|
||||
func _on_resize() -> void:
|
||||
._on_resize()
|
||||
update_controls()
|
@ -0,0 +1,13 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_editor.gd" type="Script" id=2]
|
||||
|
||||
[node name="CurveEditor" instance=ExtResource( 1 )]
|
||||
margin_left = 10.0
|
||||
margin_top = 10.0
|
||||
margin_right = -10.0
|
||||
margin_bottom = -10.0
|
||||
mouse_filter = 0
|
||||
script = ExtResource( 2 )
|
||||
[connection signal="gui_input" from="." to="." method="_on_CurveEditor_gui_input"]
|
53
game/addons/mat_maker_gd/widgets/curve_edit/curve_view.gd
Normal file
53
game/addons/mat_maker_gd/widgets/curve_edit/curve_view.gd
Normal file
@ -0,0 +1,53 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
|
||||
|
||||
export var show_axes : bool = false
|
||||
|
||||
var curve #: MMCurve
|
||||
|
||||
func _ready() -> void:
|
||||
curve = MMCurve.new()
|
||||
connect("resized", self, "_on_resize")
|
||||
update()
|
||||
|
||||
func transform_point(p : Vector2) -> Vector2:
|
||||
return (Vector2(0.0, 1.0)+Vector2(1.0, -1.0)*p)*rect_size
|
||||
|
||||
func reverse_transform_point(p : Vector2) -> Vector2:
|
||||
return Vector2(0.0, 1.0)+Vector2(1.0, -1.0)*p/rect_size
|
||||
|
||||
func _draw():
|
||||
var current_theme : Theme = get_node("/root/MainWindow").theme
|
||||
var bg = current_theme.get_stylebox("panel", "Panel").bg_color
|
||||
var fg = current_theme.get_color("font_color", "Label")
|
||||
var axes_color : Color = bg.linear_interpolate(fg, 0.25)
|
||||
var curve_color : Color = bg.linear_interpolate(fg, 0.75)
|
||||
if show_axes:
|
||||
for i in range(5):
|
||||
var p = transform_point(0.25*Vector2(i, i))
|
||||
draw_line(Vector2(p.x, 0), Vector2(p.x, rect_size.y-1), axes_color)
|
||||
draw_line(Vector2(0, p.y), Vector2(rect_size.x-1, p.y), axes_color)
|
||||
for i in range(curve.points.size()-1):
|
||||
var p1 = curve.points[i].p
|
||||
var p2 = curve.points[i+1].p
|
||||
var d = (p2.x-p1.x)/3.0
|
||||
var yac = p1.y+d*curve.points[i].rs
|
||||
var ybc = p2.y-d*curve.points[i+1].ls
|
||||
var p = transform_point(p1)
|
||||
var count : int = max(1, int((transform_point(p2).x-p.x/5.0)))
|
||||
for tt in range(count):
|
||||
var t = (tt+1.0)/count
|
||||
var omt = (1.0 - t)
|
||||
var omt2 = omt * omt
|
||||
var omt3 = omt2 * omt
|
||||
var t2 = t * t
|
||||
var t3 = t2 * t
|
||||
var x = p1.x+(p2.x-p1.x)*t
|
||||
var np = transform_point(Vector2(x, p1.y*omt3 + yac*omt2*t*3.0 + ybc*omt*t2*3.0 + p2.y*t3))
|
||||
draw_line(p, np, curve_color)
|
||||
p = np
|
||||
|
||||
func _on_resize() -> void:
|
||||
update()
|
16
game/addons/mat_maker_gd/widgets/curve_edit/curve_view.tscn
Normal file
16
game/addons/mat_maker_gd/widgets/curve_edit/curve_view.tscn
Normal file
@ -0,0 +1,16 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.gd" type="Script" id=1]
|
||||
|
||||
[node name="CurveView" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 4.0
|
||||
margin_top = 4.0
|
||||
margin_right = -4.0
|
||||
margin_bottom = -4.0
|
||||
mouse_filter = 2
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
44
game/addons/mat_maker_gd/widgets/curve_edit/slope_point.gd
Normal file
44
game/addons/mat_maker_gd/widgets/curve_edit/slope_point.gd
Normal file
@ -0,0 +1,44 @@
|
||||
extends Control
|
||||
|
||||
export var distance : float
|
||||
|
||||
var moving = false
|
||||
|
||||
const OFFSET = -Vector2(0, 0)
|
||||
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _draw():
|
||||
var current_theme : Theme = get_node("/root/MainWindow").theme
|
||||
var color : Color = current_theme.get_color("font_color", "Label")
|
||||
draw_circle(Vector2(3.0, 3.0), 3.0, color)
|
||||
|
||||
func _on_ControlPoint_gui_input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
if event.doubleclick:
|
||||
var parent = get_parent()
|
||||
var vector : Vector2
|
||||
if get_index() == 0:
|
||||
vector = parent.rect_position-parent.get_parent().get_child(parent.get_index()-1).rect_position
|
||||
else:
|
||||
vector = parent.get_parent().get_child(parent.get_index()+1).rect_position-parent.rect_position
|
||||
vector = distance*vector.normalized()
|
||||
rect_position = vector-OFFSET
|
||||
if event.control:
|
||||
get_parent().get_child(1-get_index()).rect_position = -vector-OFFSET
|
||||
get_parent().update_tangents()
|
||||
else:
|
||||
moving = true
|
||||
else:
|
||||
moving = false
|
||||
elif moving and event is InputEventMouseMotion:
|
||||
var vector = get_global_mouse_position()-get_parent().get_global_rect().position+OFFSET
|
||||
vector *= sign(vector.x)
|
||||
vector = distance*vector.normalized()
|
||||
rect_position = vector-OFFSET
|
||||
if event.control:
|
||||
get_parent().get_child(1-get_index()).rect_position = -vector-OFFSET
|
||||
get_parent().update_tangents()
|
@ -0,0 +1,30 @@
|
||||
extends Control
|
||||
|
||||
var moving : bool = false
|
||||
|
||||
const OFFSET : Vector2 = Vector2(3, 3)
|
||||
|
||||
signal moved(index)
|
||||
signal removed(index)
|
||||
|
||||
func _draw():
|
||||
var current_theme : Theme = get_node("/root/MainWindow").theme
|
||||
var color : Color = current_theme.get_color("font_color", "Label")
|
||||
draw_rect(Rect2(0, 0, 7, 7), color)
|
||||
|
||||
func initialize(p : Vector2) -> void:
|
||||
rect_position = get_parent().transform_point(p)-OFFSET
|
||||
|
||||
func _on_ControlPoint_gui_input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
moving = true
|
||||
else:
|
||||
moving = false
|
||||
get_parent().update_controls()
|
||||
elif event.button_index == BUTTON_RIGHT and event.pressed:
|
||||
emit_signal("removed", get_index())
|
||||
elif moving and event is InputEventMouseMotion:
|
||||
rect_position += event.relative
|
||||
emit_signal("moved", get_index())
|
@ -0,0 +1,15 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/polygon_edit/control_point.gd" type="Script" id=1]
|
||||
|
||||
[node name="ControlPoint" type="Control"]
|
||||
margin_left = 56.9864
|
||||
margin_top = 33.8615
|
||||
margin_right = 63.9864
|
||||
margin_bottom = 40.8615
|
||||
rect_min_size = Vector2( 7, 7 )
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
[connection signal="gui_input" from="." to="." method="_on_ControlPoint_gui_input"]
|
@ -0,0 +1,32 @@
|
||||
extends WindowDialog
|
||||
|
||||
export var closed : bool = true setget set_closed
|
||||
var previous_value
|
||||
|
||||
signal polygon_changed(polygon)
|
||||
signal return_polygon(polygon)
|
||||
|
||||
func set_closed(c : bool = true):
|
||||
closed = c
|
||||
window_title = "Edit polygon" if closed else "Edit polyline"
|
||||
$VBoxContainer/EditorContainer/PolygonEditor.set_closed(closed)
|
||||
|
||||
func _on_CurveDialog_popup_hide():
|
||||
emit_signal("return_polygon", null)
|
||||
|
||||
func _on_OK_pressed():
|
||||
emit_signal("return_polygon", $VBoxContainer/EditorContainer/PolygonEditor.polygon)
|
||||
|
||||
func _on_Cancel_pressed():
|
||||
emit_signal("return_polygon", previous_value)
|
||||
|
||||
func edit_polygon(polygon) -> Array:
|
||||
previous_value = polygon.duplicate()
|
||||
$VBoxContainer/EditorContainer/PolygonEditor.set_polygon(polygon)
|
||||
popup_centered()
|
||||
var result = yield(self, "return_polygon")
|
||||
queue_free()
|
||||
return result
|
||||
|
||||
func _on_PolygonEditor_value_changed(value):
|
||||
emit_signal("polygon_changed", value)
|
@ -0,0 +1,81 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_editor.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_dialog.gd" type="Script" id=2]
|
||||
|
||||
[node name="PolygonDialog" type="WindowDialog"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 307.0
|
||||
margin_top = 151.0
|
||||
margin_right = -508.0
|
||||
margin_bottom = -70.0
|
||||
window_title = "Edit polygon"
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 5.0
|
||||
margin_top = 5.0
|
||||
margin_right = -5.0
|
||||
margin_bottom = -5.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="EditorContainer" type="MarginContainer" parent="VBoxContainer"]
|
||||
margin_right = 455.0
|
||||
margin_bottom = 457.0
|
||||
rect_clip_content = true
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/margin_right = 4
|
||||
custom_constants/margin_top = 4
|
||||
custom_constants/margin_left = 4
|
||||
custom_constants/margin_bottom = 4
|
||||
|
||||
[node name="PolygonEditor" parent="VBoxContainer/EditorContainer" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 4.0
|
||||
margin_top = 4.0
|
||||
margin_right = 451.0
|
||||
margin_bottom = 453.0
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="VBoxContainer"]
|
||||
margin_top = 461.0
|
||||
margin_right = 455.0
|
||||
margin_bottom = 465.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
margin_top = 469.0
|
||||
margin_right = 455.0
|
||||
margin_bottom = 489.0
|
||||
|
||||
[node name="Control" type="Control" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_right = 327.0
|
||||
margin_bottom = 20.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="OK" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_left = 331.0
|
||||
margin_right = 391.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 60, 0 )
|
||||
text = "OK"
|
||||
|
||||
[node name="Cancel" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_left = 395.0
|
||||
margin_right = 455.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 60, 0 )
|
||||
text = "Cancel"
|
||||
|
||||
[connection signal="popup_hide" from="." to="." method="_on_CurveDialog_popup_hide"]
|
||||
[connection signal="value_changed" from="VBoxContainer/EditorContainer/PolygonEditor" to="." method="_on_PolygonEditor_value_changed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/OK" to="." method="_on_OK_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/Cancel" to="." method="_on_Cancel_pressed"]
|
@ -0,0 +1,38 @@
|
||||
extends Control
|
||||
|
||||
var MMPolygon = preload("res://addons/mat_maker_gd/nodes/bases/polygon_base.gd")
|
||||
|
||||
export var closed : bool = true setget set_closed
|
||||
var value = null setget set_value
|
||||
|
||||
|
||||
signal updated(polygon)
|
||||
|
||||
|
||||
func set_closed(c : bool = true):
|
||||
closed = c
|
||||
$PolygonView.set_closed(c)
|
||||
|
||||
func _ready():
|
||||
set_value(MMPolygon.new())
|
||||
|
||||
func set_value(v) -> void:
|
||||
value = v.duplicate()
|
||||
$PolygonView.polygon = value
|
||||
$PolygonView.update()
|
||||
|
||||
func _on_PolygonEdit_pressed():
|
||||
var dialog = preload("res://addons/mat_maker_gd/widgets/polygon_edit/polygon_dialog.tscn").instance()
|
||||
dialog.set_closed(closed)
|
||||
add_child(dialog)
|
||||
dialog.connect("polygon_changed", self, "on_value_changed")
|
||||
var new_polygon = dialog.edit_polygon(value)
|
||||
while new_polygon is GDScriptFunctionState:
|
||||
new_polygon = yield(new_polygon, "completed")
|
||||
if new_polygon != null:
|
||||
set_value(new_polygon)
|
||||
emit_signal("updated", new_polygon.duplicate())
|
||||
|
||||
func on_value_changed(v) -> void:
|
||||
set_value(v)
|
||||
emit_signal("updated", v.duplicate())
|
@ -0,0 +1,26 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_edit.gd" type="Script" id=1]
|
||||
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_view.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="PolygonEdit" type="Button"]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -1280.0
|
||||
margin_right = -1248.0
|
||||
margin_bottom = -688.0
|
||||
rect_min_size = Vector2( 32, 32 )
|
||||
focus_mode = 1
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="PolygonView" parent="." instance=ExtResource( 2 )]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_right = 0.0
|
||||
margin_bottom = 0.0
|
||||
|
||||
[connection signal="pressed" from="." to="." method="_on_PolygonEdit_pressed"]
|
@ -0,0 +1,46 @@
|
||||
extends "res://addons/mat_maker_gd/widgets/polygon_edit/polygon_view.gd"
|
||||
|
||||
signal value_changed(value)
|
||||
|
||||
func _ready():
|
||||
update_controls()
|
||||
|
||||
func set_polygon(p) -> void:
|
||||
polygon = p
|
||||
update()
|
||||
update_controls()
|
||||
|
||||
func update_controls() -> void:
|
||||
for c in get_children():
|
||||
c.queue_free()
|
||||
for i in polygon.points.size():
|
||||
var p = polygon.points[i]
|
||||
var control_point = preload("res://addons/mat_maker_gd/widgets/polygon_edit/control_point.tscn").instance()
|
||||
add_child(control_point)
|
||||
control_point.initialize(p)
|
||||
control_point.rect_position = transform_point(p)-control_point.OFFSET
|
||||
control_point.connect("moved", self, "_on_ControlPoint_moved")
|
||||
control_point.connect("removed", self, "_on_ControlPoint_removed")
|
||||
emit_signal("value_changed", polygon)
|
||||
|
||||
func _on_ControlPoint_moved(index):
|
||||
var control_point = get_child(index)
|
||||
polygon.points[index] = reverse_transform_point(control_point.rect_position+control_point.OFFSET)
|
||||
update()
|
||||
emit_signal("value_changed", polygon)
|
||||
|
||||
func _on_ControlPoint_removed(index):
|
||||
if polygon.remove_point(index):
|
||||
update()
|
||||
update_controls()
|
||||
|
||||
func _on_PolygonEditor_gui_input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT and event.doubleclick:
|
||||
var new_point_position = reverse_transform_point(get_local_mouse_position())
|
||||
polygon.add_point(new_point_position.x, new_point_position.y, closed)
|
||||
update_controls()
|
||||
|
||||
func _on_resize() -> void:
|
||||
._on_resize()
|
||||
update_controls()
|
@ -0,0 +1,14 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_editor.gd" type="Script" id=2]
|
||||
|
||||
[node name="PolygonEditor" instance=ExtResource( 1 )]
|
||||
margin_left = 10.0
|
||||
margin_top = 10.0
|
||||
margin_right = -10.0
|
||||
margin_bottom = -10.0
|
||||
mouse_filter = 0
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[connection signal="gui_input" from="." to="." method="_on_PolygonEditor_gui_input"]
|
@ -0,0 +1,44 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
var MMPolygon = preload("res://addons/mat_maker_gd/nodes/bases/polygon_base.gd")
|
||||
|
||||
var polygon #: MMPolygon
|
||||
|
||||
var draw_size : Vector2 = Vector2(1, 1)
|
||||
var draw_offset : Vector2 = Vector2(0, 0)
|
||||
var closed : bool = true
|
||||
|
||||
func set_closed(c : bool = true):
|
||||
closed = c
|
||||
update()
|
||||
|
||||
func _ready() -> void:
|
||||
polygon = MMPolygon.new()
|
||||
connect("resized", self, "_on_resize")
|
||||
_on_resize()
|
||||
|
||||
func transform_point(p : Vector2) -> Vector2:
|
||||
return draw_offset+p*draw_size
|
||||
|
||||
func reverse_transform_point(p : Vector2) -> Vector2:
|
||||
return (p-draw_offset)/draw_size
|
||||
|
||||
func _draw():
|
||||
var current_theme : Theme = get_node("/root/MainWindow").theme
|
||||
var bg = current_theme.get_stylebox("panel", "Panel").bg_color
|
||||
var fg = current_theme.get_color("font_color", "Label")
|
||||
var axes_color : Color = bg.linear_interpolate(fg, 0.25)
|
||||
var curve_color : Color = bg.linear_interpolate(fg, 0.75)
|
||||
draw_rect(Rect2(draw_offset, draw_size), axes_color, false)
|
||||
var tp : Vector2 = transform_point(polygon.points[polygon.points.size()-1 if closed else 0])
|
||||
for p in polygon.points:
|
||||
var tnp = transform_point(p)
|
||||
draw_line(tp, tnp, curve_color)
|
||||
tp = tnp
|
||||
|
||||
func _on_resize() -> void:
|
||||
var ds : float = min(rect_size.x, rect_size.y)
|
||||
draw_size = Vector2(ds, ds)
|
||||
draw_offset = 0.5*(rect_size-draw_size)
|
||||
update()
|
@ -0,0 +1,12 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_view.gd" type="Script" id=1]
|
||||
|
||||
[node name="PolygonView" type="Control"]
|
||||
margin_right = 64.0
|
||||
margin_bottom = 64.0
|
||||
mouse_filter = 2
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
Loading…
Reference in New Issue
Block a user