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); 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 // From http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
vec3 rgb2hsv(vec3 c) { vec3 rgb2hsv(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 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_defs = ""
var required_code = "" var required_code = ""
var required_textures = {} var required_textures = {}
var new_pass_required = false
while true: while true:
var uv = find_keyword_call(string, input) var uv = find_keyword_call(string, input)
if uv == null: if uv == null:
@ -71,6 +72,9 @@ func replace_input(string, context, input, type, src, default):
elif uv == "": elif uv == "":
print("syntax error") print("syntax error")
break break
elif uv.find("$") != -1:
new_pass_required = true
break
var src_code var src_code
if src == null: if src == null:
src_code = subst(default, context, "(%s)" % uv) 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_code += src_code.code
required_textures = src_code.textures required_textures = src_code.textures
string = string.replace("$%s(%s)" % [ input, uv ], src_code.string) 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): func is_word_letter(l):
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1 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 ] value_string = "vec4(%.9f, %.9f, %.9f, %.9f)" % [ value.r, value.g, value.b, value.a ]
elif p.type == "gradient": elif p.type == "gradient":
value_string = name+"__"+p.name+"_gradient_fct" 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: if value_string != null:
string = replace_variable(string, p.name, value_string) string = replace_variable(string, p.name, value_string)
if shader_model.has("inputs") and typeof(shader_model.inputs) == TYPE_ARRAY: if shader_model.has("inputs") and typeof(shader_model.inputs) == TYPE_ARRAY:
for i in range(shader_model.inputs.size()): var cont = true
var input = shader_model.inputs[i] while cont:
var source = get_source(i) var changed = false
var result = replace_input(string, context, input.name, input.type, source, input.default) var new_pass_required = false
while result is GDScriptFunctionState: for i in range(shader_model.inputs.size()):
result = yield(result, "completed") var input = shader_model.inputs[i]
string = result.string var source = get_source(i)
required_defs += result.defs var result = replace_input(string, context, input.name, input.type, source, input.default)
required_code += result.code while result is GDScriptFunctionState:
for t in result.textures.keys(): result = yield(result, "completed")
required_textures[t] = result.textures[t] 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 } return { string=string, defs=required_defs, code=required_code, textures=required_textures }
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): 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 = HSlider.new()
control.min_value = p.min control.min_value = p.min
control.max_value = p.max 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"): if p.has("default"):
control.value = p.default control.value = p.default
control.rect_min_size.x = 80 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] [ext_resource path="res://addons/material_maker/widgets/node_editor/parameter_float.gd" type="Script" id=1]
[node name="float" type="HBoxContainer"] [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_right = 547.0
margin_bottom = 24.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 ) script = ExtResource( 1 )
_sections_unfolded = [ "Visibility" ]
[node name="LabelMin" type="Label" parent="." index="0"] [node name="LabelMin" type="Label" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 5.0 margin_top = 5.0
margin_right = 28.0 margin_right = 28.0
margin_bottom = 19.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:" text = "Min:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Min" type="SpinBox" parent="." index="1"] [node name="Min" type="SpinBox" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 32.0 margin_left = 32.0
margin_right = 106.0 margin_right = 106.0
margin_bottom = 24.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 min_value = -65536.0
max_value = 65535.0 max_value = 65536.0
step = 0.0 step = 0.005
page = 0.0 allow_greater = true
value = 0.0 allow_lesser = true
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""
[node name="LabelMax" type="Label" parent="." index="2"] [node name="LabelMax" type="Label" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 110.0 margin_left = 110.0
margin_top = 5.0 margin_top = 5.0
margin_right = 140.0 margin_right = 140.0
margin_bottom = 19.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:" text = "Max:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Max" type="SpinBox" parent="." index="3"] [node name="Max" type="SpinBox" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 144.0 margin_left = 144.0
margin_right = 218.0 margin_right = 218.0
margin_bottom = 24.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 min_value = -65536.0
max_value = 65535.0 max_value = 65536.0
step = 0.0 step = 0.005
page = 0.0 allow_greater = true
value = 0.0 allow_lesser = true
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""
[node name="LabelStep" type="Label" parent="." index="4"] [node name="LabelStep" type="Label" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 222.0 margin_left = 222.0
margin_top = 5.0 margin_top = 5.0
margin_right = 254.0 margin_right = 254.0
margin_bottom = 19.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:" text = "Step:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Step" type="SpinBox" parent="." index="5"] [node name="Step" type="SpinBox" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 258.0 margin_left = 258.0
margin_right = 332.0 margin_right = 332.0
margin_bottom = 24.0 margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 ) step = 0.005
rect_clip_content = false allow_greater = true
mouse_filter = 0 allow_lesser = true
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 = ""
[node name="LabelDefault" type="Label" parent="." index="6"] [node name="LabelDefault" type="Label" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 336.0 margin_left = 336.0
margin_top = 5.0 margin_top = 5.0
margin_right = 386.0 margin_right = 386.0
margin_bottom = 19.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:" text = "Default:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Default" type="SpinBox" parent="." index="7"] [node name="Default" type="SpinBox" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 390.0 margin_left = 390.0
margin_right = 464.0 margin_right = 464.0
margin_bottom = 24.0 margin_bottom = 24.0
rect_pivot_offset = Vector2( 0, 0 ) min_value = -65536.0
rect_clip_content = false max_value = 65536.0
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 step = 0.0
page = 0.0 allow_greater = true
value = 0.0 allow_lesser = true
exp_edit = false
rounded = false
editable = true
prefix = ""
suffix = ""
[node name="SpinBox" type="CheckBox" parent="." index="8"] [node name="SpinBox" type="CheckBox" parent="."]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 468.0 margin_left = 468.0
margin_right = 547.0 margin_right = 547.0
margin_bottom = 24.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" text = "SpinBox"
flat = false
align = 0