Fixed shader generation and added transform, mirror and skew

Fixed shader generation with nested usage of inputs (process code until no further input substitution is possible)
This commit is contained in:
RodZill4 2019-09-12 21:16:07 +02:00
parent 59dced1c09
commit 9834571c4a
8 changed files with 60 additions and 212 deletions

View File

@ -13,25 +13,6 @@ vec3 rand3(vec2 x) {
dot(x, vec2(13.254, 5.867)))) * 43758.5453);
}
vec2 transform(vec2 uv, vec2 translate, float rotate, vec2 scale) {
vec2 rv;
uv -= vec2(0.5);
rv.x = cos(rotate)*uv.x + sin(rotate)*uv.y;
rv.y = -sin(rotate)*uv.x + cos(rotate)*uv.y;
rv /= scale;
rv += vec2(0.5);
rv -= translate;
return rv;
}
vec2 transform_repeat(vec2 uv, vec2 translate, float rotate, vec2 scale) {
return fract(transform(uv, translate, rotate, scale));
}
vec2 transform_norepeat(vec2 uv, vec2 translate, float rotate, vec2 scale) {
return clamp(transform(uv, translate, rotate, scale), vec2(0.0), vec2(1.0));
}
// From http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
vec3 rgb2hsv(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);

View File

@ -64,6 +64,7 @@ func replace_input(string, context, input, type, src, default):
var required_defs = ""
var required_code = ""
var required_textures = {}
var new_pass_required = false
while true:
var uv = find_keyword_call(string, input)
if uv == null:
@ -71,6 +72,9 @@ func replace_input(string, context, input, type, src, default):
elif uv == "":
print("syntax error")
break
elif uv.find("$") != -1:
new_pass_required = true
break
var src_code
if src == null:
src_code = subst(default, context, "(%s)" % uv)
@ -83,7 +87,7 @@ func replace_input(string, context, input, type, src, default):
required_code += src_code.code
required_textures = src_code.textures
string = string.replace("$%s(%s)" % [ input, uv ], src_code.string)
return { string=string, defs=required_defs, code=required_code, textures=required_textures }
return { string=string, defs=required_defs, code=required_code, textures=required_textures, new_pass_required=new_pass_required }
func is_word_letter(l):
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
@ -130,20 +134,33 @@ func subst(string, context, uv = ""):
value_string = "vec4(%.9f, %.9f, %.9f, %.9f)" % [ value.r, value.g, value.b, value.a ]
elif p.type == "gradient":
value_string = name+"__"+p.name+"_gradient_fct"
elif p.type == "boolean":
value_string = "true" if value else "false"
else:
print("Cannot replace parameter of type "+p.type)
if value_string != null:
string = replace_variable(string, p.name, value_string)
if shader_model.has("inputs") and typeof(shader_model.inputs) == TYPE_ARRAY:
for i in range(shader_model.inputs.size()):
var input = shader_model.inputs[i]
var source = get_source(i)
var result = replace_input(string, context, input.name, input.type, source, input.default)
while result is GDScriptFunctionState:
result = yield(result, "completed")
string = result.string
required_defs += result.defs
required_code += result.code
for t in result.textures.keys():
required_textures[t] = result.textures[t]
var cont = true
while cont:
var changed = false
var new_pass_required = false
for i in range(shader_model.inputs.size()):
var input = shader_model.inputs[i]
var source = get_source(i)
var result = replace_input(string, context, input.name, input.type, source, input.default)
while result is GDScriptFunctionState:
result = yield(result, "completed")
if string != result.string:
changed = true
if result.new_pass_required:
new_pass_required = true
string = result.string
required_defs += result.defs
required_code += result.code
for t in result.textures.keys():
required_textures[t] = result.textures[t]
cont = changed and new_pass_required
return { string=string, defs=required_defs, code=required_code, textures=required_textures }
func _get_shader_code(uv : String, output_index : int, context : MMGenContext):

View File

@ -1 +1 @@
{"name":"blend","node_position":{"x":0,"y":0},"parameters":{"amount":1,"blend_type":6},"shader_model":{"global":"vec3 blend_normal(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*c1 + (1.0-opacity)*c2;\n}\n\nvec3 blend_dissolve(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\tif (rand(uv) < opacity) {\n\t\treturn c1;\n\t} else {\n\t\treturn c2;\n\t}\n}\n\nvec3 blend_multiply(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*c1*c2 + (1.0-opacity)*c2;\n}\n\nvec3 blend_screen(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*(1.0-(1.0-c1)*(1.0-c2)) + (1.0-opacity)*c2;\n}\n\nfloat blend_overlay_f(float c1, float c2) {\n\treturn (c1 < 0.5) ? (2.0*c1*c2) : (1.0-2.0*(1.0-c1)*(1.0-c2));\n}\n\nvec3 blend_overlay(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_overlay_f(c1.x, c2.x), blend_overlay_f(c1.y, c2.y), blend_overlay_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nvec3 blend_hard_light(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*0.5*(c1*c2+blend_overlay(uv, c1, c2, 1.0)) + (1.0-opacity)*c2;\n}\n\nfloat blend_soft_light_f(float c1, float c2) {\n\treturn (c2 < 0.5) ? (2.0*c1*c2+c1*c1*(1.0-2.0*c2)) : 2.0*c1*(1.0-c2)+sqrt(c1)*(2.0*c2-1.0);\n}\n\nvec3 blend_soft_light(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_soft_light_f(c1.x, c2.x), blend_soft_light_f(c1.y, c2.y), blend_soft_light_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nfloat blend_burn_f(float c1, float c2) {\n\treturn (c1==0.0)?c1:max((1.0-((1.0-c2)/c1)),0.0);\n}\n\nvec3 blend_burn(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_burn_f(c1.x, c2.x), blend_burn_f(c1.y, c2.y), blend_burn_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nfloat blend_dodge_f(float c1, float c2) {\n\treturn (c1==1.0)?c1:min(c2/(1.0-c1),1.0);\n}\n\nvec3 blend_dodge(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_dodge_f(c1.x, c2.x), blend_dodge_f(c1.y, c2.y), blend_dodge_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nvec3 blend_lighten(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*max(c1, c2) + (1.0-opacity)*c2;\n}\n\nvec3 blend_darken(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*min(c1, c2) + (1.0-opacity)*c2;\n}\n\nvec3 blend_difference(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*clamp(c2-c1, vec3(0.0), vec3(1.0)) + (1.0-opacity)*c2;\n}\n","inputs":[{"default":"vec4($uv.x, 1.0, 1.0, 1.0)","label":"Source1","name":"s1","type":"rgba"},{"default":"vec4(1.0, $uv.y, 1.0, 1.0)","label":"Source2","name":"s2","type":"rgba"},{"default":"$amount","label":"Opacity","name":"a","type":"f"}],"instance":"","name":"Blend","outputs":[{"rgba":"vec4(blend_$blend_type($uv, $s1($uv).rgb, $s2($uv).rgb, $a($uv)*$s1($uv).a), min(1.0, $s2($uv).a+$a($uv)*$s1($uv).a))","type":"rgba"}],"parameters":[{"default":0,"label":"","name":"blend_type","type":"enum","values":[{"name":"Normal","value":"normal"},{"name":"Dissolve","value":"dissolve"},{"name":"Multiply","value":"multiply"},{"name":"Screen","value":"screen"},{"name":"Overlay","value":"overlay"},{"name":"Hard Light","value":"hard_light"},{"name":"Soft Light","value":"soft_light"},{"name":"Burn","value":"burn"},{"name":"Dodge","value":"dodge"},{"name":"Lighten","value":"lighten"},{"name":"Darken","value":"darken"},{"name":"Difference","value":"difference"}]},{"default":0.5,"label":"3:","max":1,"min":0,"name":"amount","step":0,"type":"float"}]}}
{"name":"blend","node_position":{"x":0,"y":0},"parameters":{"amount":0.935642,"blend_type":0},"shader_model":{"global":"vec3 blend_normal(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*c1 + (1.0-opacity)*c2;\n}\n\nvec3 blend_dissolve(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\tif (rand(uv) < opacity) {\n\t\treturn c1;\n\t} else {\n\t\treturn c2;\n\t}\n}\n\nvec3 blend_multiply(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*c1*c2 + (1.0-opacity)*c2;\n}\n\nvec3 blend_screen(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*(1.0-(1.0-c1)*(1.0-c2)) + (1.0-opacity)*c2;\n}\n\nfloat blend_overlay_f(float c1, float c2) {\n\treturn (c1 < 0.5) ? (2.0*c1*c2) : (1.0-2.0*(1.0-c1)*(1.0-c2));\n}\n\nvec3 blend_overlay(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_overlay_f(c1.x, c2.x), blend_overlay_f(c1.y, c2.y), blend_overlay_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nvec3 blend_hard_light(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*0.5*(c1*c2+blend_overlay(uv, c1, c2, 1.0)) + (1.0-opacity)*c2;\n}\n\nfloat blend_soft_light_f(float c1, float c2) {\n\treturn (c2 < 0.5) ? (2.0*c1*c2+c1*c1*(1.0-2.0*c2)) : 2.0*c1*(1.0-c2)+sqrt(c1)*(2.0*c2-1.0);\n}\n\nvec3 blend_soft_light(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_soft_light_f(c1.x, c2.x), blend_soft_light_f(c1.y, c2.y), blend_soft_light_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nfloat blend_burn_f(float c1, float c2) {\n\treturn (c1==0.0)?c1:max((1.0-((1.0-c2)/c1)),0.0);\n}\n\nvec3 blend_burn(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_burn_f(c1.x, c2.x), blend_burn_f(c1.y, c2.y), blend_burn_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nfloat blend_dodge_f(float c1, float c2) {\n\treturn (c1==1.0)?c1:min(c2/(1.0-c1),1.0);\n}\n\nvec3 blend_dodge(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*vec3(blend_dodge_f(c1.x, c2.x), blend_dodge_f(c1.y, c2.y), blend_dodge_f(c1.z, c2.z)) + (1.0-opacity)*c2;\n}\n\nvec3 blend_lighten(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*max(c1, c2) + (1.0-opacity)*c2;\n}\n\nvec3 blend_darken(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*min(c1, c2) + (1.0-opacity)*c2;\n}\n\nvec3 blend_difference(vec2 uv, vec3 c1, vec3 c2, float opacity) {\n\treturn opacity*clamp(c2-c1, vec3(0.0), vec3(1.0)) + (1.0-opacity)*c2;\n}\n","inputs":[{"default":"vec4($uv.x, 1.0, 1.0, 1.0)","label":"Source1","name":"s1","type":"rgba"},{"default":"vec4(1.0, $uv.y, 1.0, 1.0)","label":"Source2","name":"s2","type":"rgba"},{"default":"1.0","label":"Opacity","name":"a","type":"f"}],"instance":"","name":"Blend","outputs":[{"rgba":"vec4(blend_$blend_type($uv, $s1($uv).rgb, $s2($uv).rgb, $amount*$a($uv)*$s1($uv).a), min(1.0, $s2($uv).a+$amount*$a($uv)*$s1($uv).a))","type":"rgba"}],"parameters":[{"default":0,"label":"","name":"blend_type","type":"enum","values":[{"name":"Normal","value":"normal"},{"name":"Dissolve","value":"dissolve"},{"name":"Multiply","value":"multiply"},{"name":"Screen","value":"screen"},{"name":"Overlay","value":"overlay"},{"name":"Hard Light","value":"hard_light"},{"name":"Soft Light","value":"soft_light"},{"name":"Burn","value":"burn"},{"name":"Dodge","value":"dodge"},{"name":"Lighten","value":"lighten"},{"name":"Darken","value":"darken"},{"name":"Difference","value":"difference"}]},{"default":0.5,"label":"3:","max":1,"min":0,"name":"amount","step":0,"type":"float"}]}}

View File

@ -130,7 +130,9 @@ func update_node():
control = HSlider.new()
control.min_value = p.min
control.max_value = p.max
control.step = 0 if !p.has("step") else p.step
control.step = 0.005 if !p.has("step") else p.step
control.allow_greater = true
control.allow_lesser = true
if p.has("default"):
control.value = p.default
control.rect_min_size.x = 80

View File

@ -0,0 +1 @@
{"name":"mirror","node_position":{"x":0,"y":0},"parameters":{"direction":0,"offset":0.605},"shader_model":{"global":"vec2 uvmirror_h(vec2 uv, float offset) {\n\treturn vec2(max(0, abs(uv.x-0.5)-0.5*offset)+0.5, uv.y);\n}\nvec2 uvmirror_v(vec2 uv, float offset) {\n\treturn vec2(uv.x, max(0, abs(uv.y-0.5)-0.5*offset)+0.5);\n}","inputs":[{"default":"vec4($uv, 0, 1)","label":"","name":"i","type":"rgba"}],"instance":"","name":"Mirror","outputs":[{"rgba":"$i(uvmirror_$direction($uv, $offset))","type":"rgba"}],"parameters":[{"default":0,"label":"","name":"direction","type":"enum","values":[{"name":"Horizontal","value":"h"},{"name":"Vertical","value":"v"}]},{"default":0,"label":"","max":1,"min":0,"name":"offset","step":0.005,"type":"float","widget":"spinbox"}]}}

View File

@ -0,0 +1 @@
{"name":"skew","node_position":{"x":0,"y":0},"parameters":{"amount":-0.175,"amout":0,"direction":0,"offset":0.730769},"shader_model":{"global":"vec2 uvskew_h(vec2 uv, float amount) {\n\treturn vec2(uv.x+amount*(uv.y-0.5), uv.y);\n}\nvec2 uvskew_v(vec2 uv, float amount) {\n\treturn vec2(uv.x, uv.y+amount*(uv.x-0.5));\n}","inputs":[{"default":"vec4($uv, 0, 1)","label":"","name":"i","type":"rgba"}],"instance":"","name":"Skew","outputs":[{"rgba":"$i(uvskew_$direction($uv, $amount))","type":"rgba"}],"parameters":[{"default":0,"label":"","name":"direction","type":"enum","values":[{"name":"Horizontal","value":"h"},{"name":"Vertical","value":"v"}]},{"default":0,"label":"","max":3,"min":-3,"name":"amount","step":0.005,"type":"float","widget":"spinbox"}]}}

View File

@ -0,0 +1 @@
{"name":"transform","node_position":{"x":0,"y":0},"parameters":{"repeat":false,"rotate":0,"scale_x":1,"scale_y":1,"translate_x":0.33,"translate_y":0.095},"shader_model":{"global":"vec2 transform(vec2 uv, vec2 translate, float rotate, vec2 scale, bool repeat) {\n \tvec2 rv;\n\tuv -= vec2(0.5);\n\trv.x = cos(rotate)*uv.x + sin(rotate)*uv.y;\n\trv.y = -sin(rotate)*uv.x + cos(rotate)*uv.y;\n\trv /= scale;\n\trv += vec2(0.5);\n\trv -= translate;\n if (repeat) {\n\t\treturn fract(rv);\n\t} else {\n\t\treturn clamp(rv, vec2(0.0), vec2(1.0));\n\t}\t\n}","inputs":[{"default":"vec4($uv, 0.0, 1.0)","label":"","name":"i","type":"rgba"},{"default":"1.0","label":"","name":"tx","type":"f"},{"default":"1.0","label":"","name":"ty","type":"f"},{"default":"1.0","label":"","name":"r","type":"f"},{"default":"1.0","label":"","name":"sx","type":"f"},{"default":"1.0","label":"","name":"sy","type":"f"}],"instance":"","name":"Transform","outputs":[{"rgba":"$i(transform($uv, vec2($translate_x*(2.0*$tx($uv)-1.0), $translate_y*(2.0*$ty($uv)-1.0)), $rotate*(2.0*$r($uv)-1.0), vec2($scale_x*(2.0*$sx($uv)-1.0), $scale_y*(2.0*$sy($uv)-1.0)), $repeat))","type":"rgba"}],"parameters":[{"default":0,"label":"2:Translate X:","max":1,"min":-1,"name":"translate_x","step":0.005,"type":"float","widget":"spinbox"},{"default":0,"label":"Translate Y:","max":1,"min":-1,"name":"translate_y","step":0.005,"type":"float","widget":"spinbox"},{"default":0,"label":"Rotate:","max":720,"min":-720,"name":"rotate","step":0.005,"type":"float","widget":"spinbox"},{"default":1,"label":"Scale X:","max":50,"min":0,"name":"scale_x","step":0.005,"type":"float","widget":"spinbox"},{"default":1,"label":"Scale Y:","max":50,"min":0,"name":"scale_y","step":0.005,"type":"float","widget":"spinbox"},{"default":false,"label":"Repeat:","name":"repeat","type":"boolean"}]}}

View File

@ -3,232 +3,77 @@
[ext_resource path="res://addons/material_maker/widgets/node_editor/parameter_float.gd" type="Script" id=1]
[node name="float" type="HBoxContainer"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 547.0
margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
alignment = 0
script = ExtResource( 1 )
_sections_unfolded = [ "Visibility" ]
[node name="LabelMin" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="LabelMin" type="Label" parent="."]
margin_top = 5.0
margin_right = 28.0
margin_bottom = 19.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Min:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Min" type="SpinBox" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Min" type="SpinBox" parent="."]
margin_left = 32.0
margin_right = 106.0
margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
min_value = -65536.0
max_value = 65535.0
step = 0.0
page = 0.0
value = 0.0
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""
max_value = 65536.0
step = 0.005
allow_greater = true
allow_lesser = true
[node name="LabelMax" type="Label" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="LabelMax" type="Label" parent="."]
margin_left = 110.0
margin_top = 5.0
margin_right = 140.0
margin_bottom = 19.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Max:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Max" type="SpinBox" parent="." index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Max" type="SpinBox" parent="."]
margin_left = 144.0
margin_right = 218.0
margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
min_value = -65536.0
max_value = 65535.0
step = 0.0
page = 0.0
value = 0.0
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""
max_value = 65536.0
step = 0.005
allow_greater = true
allow_lesser = true
[node name="LabelStep" type="Label" parent="." index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="LabelStep" type="Label" parent="."]
margin_left = 222.0
margin_top = 5.0
margin_right = 254.0
margin_bottom = 19.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Step:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Step" type="SpinBox" parent="." index="5"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Step" type="SpinBox" parent="."]
margin_left = 258.0
margin_right = 332.0
margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
min_value = 0.0
max_value = 65535.0
step = 0.0
page = 0.0
value = 0.0
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""
step = 0.005
allow_greater = true
allow_lesser = true
[node name="LabelDefault" type="Label" parent="." index="6"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="LabelDefault" type="Label" parent="."]
margin_left = 336.0
margin_top = 5.0
margin_right = 386.0
margin_bottom = 19.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Default:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Default" type="SpinBox" parent="." index="7"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="Default" type="SpinBox" parent="."]
margin_left = 390.0
margin_right = 464.0
margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
min_value = 0.0
max_value = 65535.0
min_value = -65536.0
max_value = 65536.0
step = 0.0
page = 0.0
value = 0.0
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""
allow_greater = true
allow_lesser = true
[node name="SpinBox" type="CheckBox" parent="." index="8"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="SpinBox" type="CheckBox" parent="."]
margin_left = 468.0
margin_right = 547.0
margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = true
enabled_focus_mode = 2
shortcut = null
group = null
text = "SpinBox"
flat = false
align = 0