Fixed curves, and the curve editor, and added curve support for sd_shape_line.

This commit is contained in:
Relintai 2021-10-20 19:53:05 +02:00
parent 3841c50674
commit 6f2437279e
10 changed files with 224 additions and 72 deletions

View File

@ -54,7 +54,7 @@ sides = 11
radius = SubResource( 4 )
edge = SubResource( 3 )
[sub_resource type="Resource" id=64]
[sub_resource type="Resource" id=67]
script = ExtResource( 5 )
default_type = 5
default_int = 0
@ -66,7 +66,7 @@ default_color = Color( 0, 0, 0, 1 )
[sub_resource type="Resource" id=6]
script = ExtResource( 6 )
graph_position = Vector2( 300, -400 )
image = SubResource( 64 )
image = SubResource( 67 )
postfix = "-test"
[sub_resource type="Resource" id=9]
@ -339,7 +339,7 @@ default_vector2 = Vector2( 0, 0 )
default_vector3 = Vector3( 0, 0, 0 )
default_color = Color( 0, 0, 0, 1 )
[sub_resource type="Resource" id=62]
[sub_resource type="Resource" id=65]
script = ExtResource( 5 )
default_type = 1
default_int = 0
@ -356,15 +356,15 @@ default_float = 0.0
default_vector2 = Vector2( 0, 0 )
default_vector3 = Vector3( 0, 0, 0 )
default_color = Color( 0, 0, 0, 1 )
input_property = SubResource( 62 )
input_property = SubResource( 65 )
[sub_resource type="Resource" id=49]
script = ExtResource( 13 )
graph_position = Vector2( 1480, -680 )
image = SubResource( 47 )
input = SubResource( 48 )
bevel = 0.23
base = 0.2
bevel = 0.0
base = 0.17
[sub_resource type="Resource" id=53]
script = ExtResource( 5 )
@ -424,13 +424,7 @@ output = SubResource( 59 )
center = Vector2( 0.04, 0 )
size = Vector2( 0.3, 0.2 )
[sub_resource type="Resource" id=63]
script = ExtResource( 16 )
graph_position = Vector2( 1060, -400 )
points = PoolVector2Array( 0.2, 0.2, 0.7, 0.4, 0.858401, 0.631436, 0.672764, 0.875339, 0.396341, 0.873984, 0.25542, 0.856369, 0.143902, 0.556369 )
output = SubResource( 62 )
[sub_resource type="Resource" id=65]
[sub_resource type="Resource" id=62]
script = ExtResource( 5 )
default_type = 1
default_int = 0
@ -439,13 +433,20 @@ default_vector2 = Vector2( 0, 0 )
default_vector3 = Vector3( 0, 0, 0 )
default_color = Color( 0, 0, 0, 1 )
[sub_resource type="Resource" id=63]
script = ExtResource( 16 )
graph_position = Vector2( 960, -440 )
points = PoolVector2Array( 0.2, 0.2, 0.7, 0.4, 0.858401, 0.631436, 0.672764, 0.875339, 0.396341, 0.873984, 0.25542, 0.856369, 0.143902, 0.556369 )
output = SubResource( 62 )
[sub_resource type="Resource" id=66]
script = ExtResource( 17 )
graph_position = Vector2( 1280, -280 )
graph_position = Vector2( 1260, -580 )
points = PoolRealArray( 0, 1, 0, 0, 0.154647, 0.9653, 0, 0.509482, 0.314904, 0.787066, 0, -0.181703, 0.461538, 0.768139, -2.54259, 1.21581, 0.665064, 0.839117, 4.01892, 0, 0.872596, 0.911672, 0, 0, 0.893429, 0.580442, 0, 0, 1, 1, 0, 0 )
output = SubResource( 65 )
A = Vector2( -0.3, -0.3 )
B = Vector2( 0.3, 0.3 )
width = 0.1
A = Vector2( -0.3, -0.36 )
B = Vector2( 0.25, 0.35 )
width = 0.07
[resource]
script = ExtResource( 1 )

View File

@ -10,7 +10,7 @@ class Point:
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) ]
export(PoolRealArray) var points = [ 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0 ]
func to_string() -> String:
var rv = PoolStringArray()
@ -24,38 +24,84 @@ func clear() -> void:
curve_changed()
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:
var indx : int = points.size() / 4
for i in indx:
var ii : int = i * 4
if x < points[ii]:
if ls == INF:
ls == 0
if rs == INF:
rs == 0
points.insert(i, Point.new(x, y, ls, rs))
points.insert(ii, x)
points.insert(ii + 1, y)
points.insert(ii + 2, ls)
points.insert(ii + 3, rs)
curve_changed()
return
points.append(Point.new(x, y, ls, rs))
points.append(x)
points.append(y)
points.append(ls)
points.append(rs)
curve_changed()
func remove_point(index : int) -> bool:
func remove_point(i : int) -> bool:
var index : int = i * 4
if index <= 0 or index >= points.size() - 1:
return false
else:
points.remove(index)
points.remove(index)
points.remove(index)
points.remove(index)
curve_changed()
return true
func get_point_count() -> int:
return points.size()
return points.size() / 4
func set_point(i : int, v : Point) -> void:
points[i] = v
var indx : int = i * 4
points[indx + 0] = v.p.x
points[indx + 1] = v.p.y
points[indx + 2] = v.ls
points[indx + 3] = v.rs
curve_changed()
func set_poins(v : PoolRealArray) -> void:
#points[i] = v
curve_changed()
func get_point(i : int) -> Point:
var indx : int = i * 4
return Point.new(points[indx + 0], points[indx + 1], points[indx + 2], points[indx + 3])
func get_points() -> Array:
var arr : Array = Array()
var c : int = get_point_count()
for i in range(c):
arr.append(get_point(i))
return arr
func set_points(arr : Array, notify : bool = true) -> void:
points.resize(0)
for p in arr:
points.append(p.p.x)
points.append(p.p.y)
points.append(p.ls)
points.append(p.rs)
if notify:
curve_changed()
func curve_changed() -> void:
_curve_changed()

View File

@ -0,0 +1,85 @@
tool
extends Reference
const Commons = preload("res://addons/mat_maker_gd/nodes/common/commons.gd")
#Based on MaterialMaker's curve.gd
#Curve PoolRealArray: p.x, p.y, ls, rs, p.x, p.y ....
#class Point:
# var p : Vector2
# var ls : float
# var rs : float
#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
static func curve(x : float, points : PoolRealArray) -> float:
if points.size() % 4 != 0 || points.size() < 8:
return 0.0
var ps : int = points.size() / 4
for i in range(ps - 1):
var pi : int = i * 4
var pip1 : int = (i + 1) * 4
if i < ps - 2:
# if (x <= p_"+name+"_"+str(i+1)+"_x)
if x > points[pip1]:
continue
#float dx = x - p_"+name+"_"+str(i)+"_x;
var dx : float = x - points[pi];
#var d : float = p_"+name+"_"+str(i+1)+"_x - p_"+name+"_"+str(i)+"_x;
var d : float = points[pi + 1] - points[pi];
var t : float = dx / d
var omt : float = (1.0 - t)
var omt2 : float = omt * omt
var omt3 : float = omt2 * omt
var t2 : float = t * t
var t3 : float = t2 * t
d /= 3.0
# var y1 : float = p_"+name+"_"+str(i)+"_y
var y1 : float = points[pi + 1]
# var yac : float = p_"+name+"_"+str(i)+"_y + d*p_"+name+"_"+str(i)+"_rs
var yac : float = points[pi + 1] + d * points[pi + 3]
# var ybc : float = p_"+name+"_"+str(i+1)+"_y - d*p_"+name+"_"+str(i+1)+"_ls
var ybc : float = points[pip1 + 1] - d * points[pip1 + 2]
# var y2 : float = p_"+name+"_"+str(i+1)+"_y
var y2 : float = points[pip1 + 1]
return y1 * omt3 + yac * omt2 * t * 3.0 + ybc * omt * t2 * 3.0 + y2 * t3;
return 0.0

View File

@ -3,6 +3,7 @@ extends "res://addons/mat_maker_gd/nodes/bases/curve_base.gd"
const Commons = preload("res://addons/mat_maker_gd/nodes/common/commons.gd")
var SDF2D = preload("res://addons/mat_maker_gd/nodes/common/sdf2d.gd")
var Curves = preload("res://addons/mat_maker_gd/nodes/common/curves.gd")
export(Resource) var output : Resource
export(Vector2) var A : Vector2 = Vector2(-0.3, -0.3)
@ -33,7 +34,7 @@ func get_property_value(uv : Vector2) -> float:
#$(name_uv)_sdl.x - $r * $profile($(name_uv)_sdl.y)
return line.x
return line.x - width * Curves.curve(line.y, points)
#a
func get_a() -> Vector2:
@ -65,9 +66,6 @@ func set_width(val : float) -> void:
emit_changed()
output.emit_changed()
func polygon_changed() -> void:
_polygon_changed()
func _polygon_changed() -> void:
func _curve_changed() -> void:
emit_changed()
output.emit_changed()

View File

@ -3,31 +3,35 @@ extends WindowDialog
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
var previous_value
var previous_points : Array
var curve
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)
queue_free()
func _on_OK_pressed():
emit_signal("return_curve", $VBoxContainer/EditorContainer/CurveEditor.curve)
emit_signal("curve_changed", curve)
curve.curve_changed()
queue_free()
func _on_Cancel_pressed():
emit_signal("return_curve", previous_value)
curve.set_points(previous_points)
emit_signal("curve_changed", curve)
func edit_curve(curve) -> Array:
previous_value = curve.duplicate()
queue_free()
func edit_curve(c) -> void:
curve = c
previous_points = curve.get_points()
$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)

View File

@ -5,29 +5,20 @@ 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
value = v
$CurveView.set_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())
dialog.edit_curve(value)
func on_value_changed(v) -> void:
set_value(v)
emit_signal("updated", v.duplicate())
#set_value(v)
emit_signal("updated", v)
$CurveView.update()

View File

@ -18,4 +18,5 @@ __meta__ = {
}
[node name="CurveView" parent="." instance=ExtResource( 2 )]
[connection signal="pressed" from="." to="." method="_on_CurveEdit_pressed"]

View File

@ -12,39 +12,54 @@ func set_curve(c) -> void:
update_controls()
func update_controls() -> void:
if !curve:
return
for c in get_children():
c.queue_free()
for i in curve.points.size():
var p = curve.points[i]
var points = curve.get_points()
for i in points.size():
var p = 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:
if i == 0 or i == 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
var min_x = transform_point(points[i-1].p).x+1
var max_x = transform_point(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 points : Array = curve.get_points()
var control_point = get_child(index)
curve.points[index].p = reverse_transform_point(control_point.rect_position+control_point.OFFSET)
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
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
points[index].rs = -slope_vector.y / slope_vector.x
curve.set_points(points, false)
update()
emit_signal("value_changed", curve)

View File

@ -8,10 +8,14 @@ export var show_axes : bool = false
var curve #: MMCurve
func _ready() -> void:
curve = MMCurve.new()
# curve = MMCurve.new()
connect("resized", self, "_on_resize")
update()
func set_curve(val) -> void:
curve = val
update()
func transform_point(p : Vector2) -> Vector2:
return (Vector2(0.0, 1.0)+Vector2(1.0, -1.0)*p)*rect_size
@ -19,6 +23,9 @@ func reverse_transform_point(p : Vector2) -> Vector2:
return Vector2(0.0, 1.0)+Vector2(1.0, -1.0)*p/rect_size
func _draw():
if !curve:
return
# var current_theme : Theme = get_node("/root/MainWindow").theme
#
# var bg = current_theme.get_stylebox("panel", "Panel").bg_color
@ -36,14 +43,17 @@ func _draw():
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 points = curve.get_points()
for i in range(points.size() - 1):
var p1 = points[i].p
var p2 = 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 yac = p1.y+d*points[i].rs
var ybc = p2.y-d*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)

View File

@ -45,4 +45,5 @@ func _on_ControlPoint_gui_input(event):
rect_position = vector-OFFSET
if event.control:
get_parent().get_child(1-get_index()).rect_position = -vector-OFFSET
get_parent().update_tangents()