From 59decb667a561e82bb301e18b4030c31b04467da Mon Sep 17 00:00:00 2001 From: Tanasart <22589759+Ttanasart-pt@users.noreply.github.com> Date: Sun, 16 Apr 2023 11:53:46 +0200 Subject: [PATCH] Morph surface --- PixelComposer.resource_order | 3 + PixelComposer.yyp | 4 + scripts/nodeValue_drawer/nodeValue_drawer.gml | 13 +- scripts/node_data/node_data.gml | 2 + .../node_morph_surface/node_alpha_to_grey.yy | 12 ++ scripts/node_morph_surface/node_bw.yy | 12 ++ .../node_color_adjustment.yy | 12 ++ .../node_color_replacement.yy | 12 ++ scripts/node_morph_surface/node_greyscale.yy | 12 ++ .../node_morph_surface/node_morph_surface.gml | 46 +++++++ .../node_morph_surface/node_morph_surface.yy | 11 ++ scripts/node_morph_surface/node_outline.yy | 12 ++ scripts/node_path_eval/node_path_eval.gml | 23 +++- scripts/node_registry/node_registry.gml | 3 +- scripts/node_transform/node_transform.gml | 31 ++--- scripts/node_value/node_value.gml | 10 +- scripts/textArea/textArea.gml | 19 +-- scripts/textBox/textBox.gml | 2 +- shaders/sh_morph_surface/sh_morph_surface.fsh | 129 ++++++++++++++++++ shaders/sh_morph_surface/sh_morph_surface.vsh | 18 +++ shaders/sh_morph_surface/sh_morph_surface.yy | 10 ++ .../3f1a7d2b-2007-4c49-be21-12931e1667df.png | Bin 0 -> 1428 bytes .../cca573c2-d140-461a-8851-7fa9d2325537.png | Bin 0 -> 1428 bytes .../s_node_morph_surface.yy | 74 ++++++++++ 24 files changed, 427 insertions(+), 43 deletions(-) create mode 100644 scripts/node_morph_surface/node_alpha_to_grey.yy create mode 100644 scripts/node_morph_surface/node_bw.yy create mode 100644 scripts/node_morph_surface/node_color_adjustment.yy create mode 100644 scripts/node_morph_surface/node_color_replacement.yy create mode 100644 scripts/node_morph_surface/node_greyscale.yy create mode 100644 scripts/node_morph_surface/node_morph_surface.gml create mode 100644 scripts/node_morph_surface/node_morph_surface.yy create mode 100644 scripts/node_morph_surface/node_outline.yy create mode 100644 shaders/sh_morph_surface/sh_morph_surface.fsh create mode 100644 shaders/sh_morph_surface/sh_morph_surface.vsh create mode 100644 shaders/sh_morph_surface/sh_morph_surface.yy create mode 100644 sprites/s_node_morph_surface/3f1a7d2b-2007-4c49-be21-12931e1667df.png create mode 100644 sprites/s_node_morph_surface/layers/3f1a7d2b-2007-4c49-be21-12931e1667df/cca573c2-d140-461a-8851-7fa9d2325537.png create mode 100644 sprites/s_node_morph_surface/s_node_morph_surface.yy diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index d649b3767..c88ea7faa 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -140,6 +140,7 @@ {"name":"sprites","order":12,"path":"folders/sprites.yy",}, {"name":"gameframe","order":2,"path":"folders/sprites/gameframe.yy",}, {"name":"widgets","order":5,"path":"folders/widgets.yy",}, + {"name":"morph","order":54,"path":"folders/shader/morph.yy",}, ], "ResourceOrderSettings": [ {"name":"s_node_corner","order":16,"path":"sprites/s_node_corner/s_node_corner.yy",}, @@ -927,6 +928,7 @@ {"name":"sh_shadow_cast_light_sep","order":1,"path":"shaders/sh_shadow_cast_light_sep/sh_shadow_cast_light_sep.yy",}, {"name":"node_grid","order":16,"path":"scripts/node_grid/node_grid.yy",}, {"name":"node_edge_detect","order":8,"path":"scripts/node_edge_detect/node_edge_detect.yy",}, + {"name":"node_morph_surface","order":5,"path":"scripts/node_morph_surface/node_morph_surface.yy",}, {"name":"node_tunnel_in","order":6,"path":"scripts/node_tunnel_in/node_tunnel_in.yy",}, {"name":"node_anim_priority","order":2,"path":"scripts/node_anim_priority/node_anim_priority.yy",}, {"name":"s_node_fluidSim_render","order":4,"path":"sprites/s_node_fluidSim_render/s_node_fluidSim_render.yy",}, @@ -1095,6 +1097,7 @@ {"name":"sample_projects","order":6,"path":"scripts/sample_projects/sample_projects.yy",}, {"name":"load_function","order":2,"path":"scripts/load_function/load_function.yy",}, {"name":"draw_fit","order":12,"path":"scripts/draw_fit/draw_fit.yy",}, + {"name":"s_node_morph_surface","order":56,"path":"sprites/s_node_morph_surface/s_node_morph_surface.yy",}, {"name":"fd_rectangle_get_velocity_dissipation_type","order":20,"path":"scripts/fd_rectangle_get_velocity_dissipation_type/fd_rectangle_get_velocity_dissipation_type.yy",}, {"name":"s_node_3d_transform","order":4,"path":"sprites/s_node_3d_transform/s_node_3d_transform.yy",}, {"name":"s_node_output","order":7,"path":"sprites/s_node_output/s_node_output.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index bfc3f79b8..b88c8e43a 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -176,6 +176,7 @@ {"resourceType":"GMFolder","resourceVersion":"1.0","name":"Steamworks","folderPath":"folders/Steamworks.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"UGC","folderPath":"folders/Steamworks/UGC.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"widgets","folderPath":"folders/widgets.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"morph","folderPath":"folders/shader/morph.yy",}, ], "IncludedFiles": [ {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"ApolloHelp.html","CopyToMask":-1,"filePath":"datafiles",}, @@ -1436,6 +1437,7 @@ {"id":{"name":"fd_rectangle_get_initial_value_pressure","path":"scripts/fd_rectangle_get_initial_value_pressure/fd_rectangle_get_initial_value_pressure.yy",},}, {"id":{"name":"node_timeline_preview","path":"scripts/node_timeline_preview/node_timeline_preview.yy",},}, {"id":{"name":"__polygon","path":"scripts/__polygon/__polygon.yy",},}, + {"id":{"name":"sh_morph_surface","path":"shaders/sh_morph_surface/sh_morph_surface.yy",},}, {"id":{"name":"o_dialog_fontscrollbox","path":"objects/o_dialog_fontscrollbox/o_dialog_fontscrollbox.yy",},}, {"id":{"name":"s_node_vfx_output","path":"sprites/s_node_vfx_output/s_node_vfx_output.yy",},}, {"id":{"name":"sh_greyscale","path":"shaders/sh_greyscale/sh_greyscale.yy",},}, @@ -1722,6 +1724,7 @@ {"id":{"name":"sh_shadow_cast_light_sep","path":"shaders/sh_shadow_cast_light_sep/sh_shadow_cast_light_sep.yy",},}, {"id":{"name":"node_grid","path":"scripts/node_grid/node_grid.yy",},}, {"id":{"name":"node_edge_detect","path":"scripts/node_edge_detect/node_edge_detect.yy",},}, + {"id":{"name":"node_morph_surface","path":"scripts/node_morph_surface/node_morph_surface.yy",},}, {"id":{"name":"node_tunnel_in","path":"scripts/node_tunnel_in/node_tunnel_in.yy",},}, {"id":{"name":"node_anim_priority","path":"scripts/node_anim_priority/node_anim_priority.yy",},}, {"id":{"name":"s_node_fluidSim_render","path":"sprites/s_node_fluidSim_render/s_node_fluidSim_render.yy",},}, @@ -1916,6 +1919,7 @@ {"id":{"name":"load_function","path":"scripts/load_function/load_function.yy",},}, {"id":{"name":"draw_fit","path":"scripts/draw_fit/draw_fit.yy",},}, {"id":{"name":"ds_map","path":"scripts/ds_map/ds_map.yy",},}, + {"id":{"name":"s_node_morph_surface","path":"sprites/s_node_morph_surface/s_node_morph_surface.yy",},}, {"id":{"name":"fd_rectangle_get_velocity_dissipation_type","path":"scripts/fd_rectangle_get_velocity_dissipation_type/fd_rectangle_get_velocity_dissipation_type.yy",},}, {"id":{"name":"s_node_3d_transform","path":"sprites/s_node_3d_transform/s_node_3d_transform.yy",},}, {"id":{"name":"s_node_output","path":"sprites/s_node_output/s_node_output.yy",},}, diff --git a/scripts/nodeValue_drawer/nodeValue_drawer.gml b/scripts/nodeValue_drawer/nodeValue_drawer.gml index 09b1b1b3e..002369112 100644 --- a/scripts/nodeValue_drawer/nodeValue_drawer.gml +++ b/scripts/nodeValue_drawer/nodeValue_drawer.gml @@ -44,7 +44,8 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover, _focus, _scr butx += ui(20); if(!global_var) { if(jun.expUse) { - draw_sprite_ui_uniform(THEME.node_use_expression, jun.expTree.validate()? 0 : 2, butx, lb_y, 1,, 0.8); + var validated = is_struct(jun.expTree) && jun.expTree.validate(); + draw_sprite_ui_uniform(THEME.node_use_expression, validated? 0 : 2, butx, lb_y, 1,, 0.8); } else { index = jun.visible; draw_sprite_ui_uniform(THEME.junc_visible, index, butx, lb_y, 1,, 0.8); @@ -186,13 +187,13 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover, _focus, _scr if(jun.expUse) { var expValid = jun.expTree != noone && jun.expTree.validate(); - jun.global_edit.boxColor = expValid? COLORS._main_value_positive : COLORS._main_value_negative; + jun.express_edit.boxColor = expValid? COLORS._main_value_positive : COLORS._main_value_negative; - jun.global_edit.setActiveFocus(_focus, _hover); - jun.global_edit.setInteract(jun.value_from == noone); - if(_focus) jun.global_edit.register(_scrollPane); + jun.express_edit.setActiveFocus(_focus, _hover); + jun.express_edit.setInteract(jun.value_from == noone); + if(_focus) jun.express_edit.register(_scrollPane); - var wd_h = jun.global_edit.draw(editBoxX, editBoxY, editBoxW, editBoxH, jun.expression, _m); + var wd_h = jun.express_edit.draw(editBoxX, editBoxY, editBoxW, editBoxH, jun.expression, _m); widH = lineBreak? wd_h : 0; } else if(jun.editWidget) { jun.editWidget.setActiveFocus(_focus, _hover); diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index ae0eedf1f..24e2f6a3d 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -53,6 +53,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x inspectInput1 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); inspectInput2 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + updateAction = nodeValue("Update", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + show_input_name = false; show_output_name = false; diff --git a/scripts/node_morph_surface/node_alpha_to_grey.yy b/scripts/node_morph_surface/node_alpha_to_grey.yy new file mode 100644 index 000000000..fde448fca --- /dev/null +++ b/scripts/node_morph_surface/node_alpha_to_grey.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_alpha_to_grey", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_morph_surface/node_bw.yy b/scripts/node_morph_surface/node_bw.yy new file mode 100644 index 000000000..6d2681493 --- /dev/null +++ b/scripts/node_morph_surface/node_bw.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_bw", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_morph_surface/node_color_adjustment.yy b/scripts/node_morph_surface/node_color_adjustment.yy new file mode 100644 index 000000000..8df16cc8c --- /dev/null +++ b/scripts/node_morph_surface/node_color_adjustment.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_color_adjustment", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_morph_surface/node_color_replacement.yy b/scripts/node_morph_surface/node_color_replacement.yy new file mode 100644 index 000000000..024aa6a80 --- /dev/null +++ b/scripts/node_morph_surface/node_color_replacement.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "process", + "path": "folders/nodes/data/process.yy", + }, + "resourceVersion": "1.0", + "name": "node_color_replacement", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_morph_surface/node_greyscale.yy b/scripts/node_morph_surface/node_greyscale.yy new file mode 100644 index 000000000..ee372977e --- /dev/null +++ b/scripts/node_morph_surface/node_greyscale.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_greyscale", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_morph_surface/node_morph_surface.gml b/scripts/node_morph_surface/node_morph_surface.gml new file mode 100644 index 000000000..75473b715 --- /dev/null +++ b/scripts/node_morph_surface/node_morph_surface.gml @@ -0,0 +1,46 @@ +function Node_Morph_Surface(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Morph Surface"; + + inputs[| 0] = nodeValue("Surface from", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0); + + inputs[| 1] = nodeValue("Surface to", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0); + + inputs[| 2] = nodeValue("Morph amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.slider, [ 0, 1, 0.01 ]); + + inputs[| 3] = nodeValue("Threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.5) + .setDisplay(VALUE_DISPLAY.slider, [ 0, 1, 0.01 ]); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ + ["Surface", true], 0, 1, + ["Morph", false], 2, 3, + ]; + + attribute_surface_depth(); + attribute_interpolation(); + + static process_data = function(_outSurf, _data, _output_index, _array_index) { + var sFrom = _data[0]; + var sTo = _data[1]; + var amo = _data[2]; + var thres = _data[3]; + + if(!is_surface(sFrom)) return _outSurf; + if(!is_surface(sTo)) return _outSurf; + + surface_set_shader(_outSurf, sh_morph_surface); + shader_set_interpolation(_data[0]); + shader_set_surface("sFrom", sFrom); + shader_set_surface("sTo", sTo); + shader_set_f("dimension", surface_get_width(sFrom), surface_get_height(sTo)); + shader_set_f("amount", amo); + shader_set_f("threshold", thres); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, surface_get_width(sFrom), surface_get_height(sTo)); + surface_reset_shader(); + + return _outSurf; + } +} \ No newline at end of file diff --git a/scripts/node_morph_surface/node_morph_surface.yy b/scripts/node_morph_surface/node_morph_surface.yy new file mode 100644 index 000000000..49fdc32d6 --- /dev/null +++ b/scripts/node_morph_surface/node_morph_surface.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_morph_surface", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "warps", + "path": "folders/nodes/data/filter/warps.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_morph_surface/node_outline.yy b/scripts/node_morph_surface/node_outline.yy new file mode 100644 index 000000000..86468bc09 --- /dev/null +++ b/scripts/node_morph_surface/node_outline.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "process", + "path": "folders/nodes/data/process.yy", + }, + "resourceVersion": "1.0", + "name": "node_outline", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_path_eval/node_path_eval.gml b/scripts/node_path_eval/node_path_eval.gml index 2a8a49f7a..7b07a389a 100644 --- a/scripts/node_path_eval/node_path_eval.gml +++ b/scripts/node_path_eval/node_path_eval.gml @@ -9,16 +9,31 @@ function Node_Path_Sample(_x, _y, _group = noone) : Node_Processor(_x, _y, _grou inputs[| 1] = nodeValue("Ratio", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0); + inputs[| 2] = nodeValue("Type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ "Loop", "Ping pong" ]); + outputs[| 0] = nodeValue("Result", self, JUNCTION_CONNECT.output, VALUE_TYPE.float, [ 0, 0 ]) .setDisplay(VALUE_DISPLAY.vector); function process_data(_output, _data, _output_index, _array_index = 0) { var _path = _data[0]; var _rat = _data[1]; - if(_path == noone) - return [ 0, 0 ]; - if(!struct_has(_path, "getPointRatio")) - return [ 0, 0 ]; + var _mod = _data[2]; + + if(_path == noone) return [ 0, 0 ]; + if(!struct_has(_path, "getPointRatio")) return [ 0, 0 ]; + + switch(_mod) { + case 0 : break; + case 1 : + var fl = floor(_rat); + var fr = frac(_rat); + + if(fl % 2 == 1 && fr != 0) + fr = 1 - fr; + _rat = fr; + break; + } return _path.getPointRatio(_rat).toArray(); } diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index fc1fccd3c..fbf019f8b 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -276,6 +276,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { addNodeObject(filter, "Displace", s_node_displace, "Node_Displace", [1, Node_Displace], ["distort"], "Distort image using another image as a map."); addNodeObject(filter, "Texture Remap", s_node_texture_map, "Node_Texture_Remap", [1, Node_Texture_Remap],, "Remap image using texture map. Where red channel control x position and green channel control y position."); addNodeObject(filter, "Time Remap", s_node_time_map, "Node_Time_Remap", [1, Node_Time_Remap],, "Remap image using texture as time map. Where brighter pixel means using pixel from an older frame."); + addNodeObject(filter, "Morph Surface", s_node_morph_surface, "Node_Morph_Surface", [1, Node_Morph_Surface],, "Morph pixel bewteen two surfaces."); ds_list_add(filter, "Effects"); addNodeObject(filter, "Outline", s_node_border, "Node_Outline", [1, Node_Outline], ["border"], "Add border to the image."); @@ -461,7 +462,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { addNodeObject(values, "Path", s_node_path, "Node_Path", [1, Node_Path]); addNodeObject(values, "Path Anchor", s_node_path_anchor, "Node_Path_Anchor", [1, Node_Path_Anchor]).setVersion(1140); addNodeObject(values, "Path Array", s_node_path_array, "Node_Path_Array", [1, Node_Path_Array]).setVersion(1137); - addNodeObject(values, "Sample Path", s_node_path_sample, "Node_Path_Sample", [1, Node_Path_Sample],, "Sample a 2D position from a path"); + addNodeObject(values, "Sample Path", s_node_path_sample, "Node_Path_Sample", [1, Node_Path_Sample], ["path sample"], "Sample a 2D position from a path"); addNodeObject(values, "Blend Path", s_node_path_blend, "Node_Path_Blend", [1, Node_Path_Blend],, "Blend between 2 paths."); addNodeObject(values, "Remap Path", s_node_path_map, "Node_Path_Map_Area", [1, Node_Path_Map_Area],, "Scale path to fit a given area.").setVersion(1130); addNodeObject(values, "Transform Path", s_node_path_transform, "Node_Path_Transform", [1, Node_Path_Transform]).setVersion(1130); diff --git a/scripts/node_transform/node_transform.gml b/scripts/node_transform/node_transform.gml index 91569daa7..67c4514d5 100644 --- a/scripts/node_transform/node_transform.gml +++ b/scripts/node_transform/node_transform.gml @@ -1,7 +1,8 @@ enum OUTPUT_SCALING { same_as_input, constant, - relative + relative, + scale } function Node_Transform(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { @@ -36,7 +37,7 @@ function Node_Transform(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) .setDisplay(VALUE_DISPLAY.slider, [0, 1, 0.01]); inputs[| 9] = nodeValue("Output dimension type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, OUTPUT_SCALING.same_as_input) - .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Same as input", "Constant", "Relative to input" ]); + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Same as input", "Constant", "Relative to input", "Scale" ]); inputs[| 10] = nodeValue("Round position", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false, "Round position to the closest integer value to avoid jittering."); @@ -62,6 +63,7 @@ function Node_Transform(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) var _surf = getSingleValue(0, arr); var _out_type = getSingleValue(9, arr); var _out = getSingleValue(1, arr); + var _scale = getSingleValue(6, arr); var ww, hh; switch(_out_type) { @@ -70,13 +72,17 @@ function Node_Transform(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) hh = surface_get_height(_surf); break; case OUTPUT_SCALING.relative : - ww = surface_get_width(_surf) * _out[0]; + ww = surface_get_width(_surf) * _out[0]; hh = surface_get_height(_surf) * _out[1]; break; case OUTPUT_SCALING.constant : ww = _out[0]; hh = _out[1]; break; + case OUTPUT_SCALING.scale : + ww = surface_get_width(_surf) * _scale[0]; + hh = surface_get_height(_surf) * _scale[1]; + break; } return [ww, hh]; @@ -98,20 +104,6 @@ function Node_Transform(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) _surf = _surf[preview_index]; } - var ww, hh; - - switch(_out_type) { - case OUTPUT_SCALING.same_as_input : - case OUTPUT_SCALING.relative : - ww = surface_get_width(_surf) * _sca[0]; - hh = surface_get_height(_surf) * _sca[1]; - break; - case OUTPUT_SCALING.constant : - ww = _out[0] * _sca[0]; - hh = _out[1] * _sca[1]; - break; - } - inputs[| 3].setValue([ 0.5, 0.5]); inputs[| 2].setValue([ surface_get_width(_surf) / 2, surface_get_height(_surf) / 2 ]); } @@ -171,6 +163,11 @@ function Node_Transform(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) _ww = ww * out[0]; _hh = hh * out[1]; break; + case OUTPUT_SCALING.scale : + inputs[| 1].setVisible(false); + _ww = ww * sca[0]; + _hh = hh * sca[1]; + break; } if(_ww <= 0 || _hh <= 0) return; _outSurf = surface_verify(_outSurf, _ww, _hh, cDep); diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 91e6339a4..0f8debeb5 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -400,13 +400,13 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru expression = ""; expTree = noone; - global_edit = new textBox(TEXTBOX_INPUT.text, function(str) { + express_edit = new textArea(TEXTBOX_INPUT.text, function(str) { expression = str; expTree = evaluateFunctionTree(expression); node.triggerRender(); }); - global_edit.boxColor = COLORS._main_value_positive; - global_edit.align = fa_left; + express_edit.boxColor = COLORS._main_value_positive; + express_edit.align = fa_left; static setDefault = function(vals) { if(LOADING || APPENDING) return self; @@ -1058,8 +1058,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } else if(value_from != self) val = value_from.getValueRecursive(_time); - if(expUse) - val[0] = is_struct(expTree)? expTree.eval(val[0]) : 0; + if(expUse && is_struct(expTree) && expTree.validate()) + val[0] = expTree.eval(val[0]); return val; } diff --git a/scripts/textArea/textArea.gml b/scripts/textArea/textArea.gml index 3e2701aee..c1058824d 100644 --- a/scripts/textArea/textArea.gml +++ b/scripts/textArea/textArea.gml @@ -8,6 +8,8 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod font = f_p0; hide = false; line_width = 1000; + color = COLORS._main_text; + boxColor = c_white; auto_update = false; @@ -278,7 +280,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod var _xx = _x, _ch, _chw; var target = -999; - draw_set_text(font, fa_left, fa_top, COLORS._main_text); + draw_set_text(font, fa_left, fa_top, color); draw_set_alpha(0.5 + 0.5 * interactable) var ch_x = _x; @@ -389,10 +391,10 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod var line_count = max(min_lines, array_length(_input_text_line)); hh = max(_h, ui(14) + c_h * line_count); - draw_sprite_stretched(THEME.textbox, 3, _x, _y, _w, hh); + draw_sprite_stretched_ext(THEME.textbox, 3, _x, _y, _w, hh, boxColor, 1); if(format == TEXT_AREA_FORMAT.code) { - draw_sprite_stretched(THEME.textbox_code, 0, _x, _y, ui(code_line_width), hh); + draw_sprite_stretched_ext(THEME.textbox_code, 0, _x, _y, ui(code_line_width), hh, boxColor, 1); draw_set_text(f_p1, fa_right, fa_top, COLORS._main_text_sub); var lx = _x + ui(code_line_width - 8); @@ -407,7 +409,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod if(self == WIDGET_CURRENT) { draw_set_text(font, fa_left, fa_top, COLORS._main_text); - draw_sprite_stretched_ext(THEME.textbox, 2, _x, _y, _w, hh, COLORS._main_accent, 1); + draw_sprite_stretched_ext(THEME.textbox, 2, _x, _y, _w, hh, boxColor, 1); editText(); #region cursor @@ -591,14 +593,13 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod } else { if(hover && hoverRect) { if(hide) - draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, hh, c_white, 0.5); + draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, hh, boxColor, 0.5); else - draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, hh, c_white, 0.5 + 0.5 * interactable); + draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, hh, boxColor, 0.5 + 0.5 * interactable); if(mouse_press(mb_left, active)) activate(); - } else if(!hide) { - draw_sprite_stretched(THEME.textbox, 0, _x, _y, _w, hh); - } + } else if(!hide) + draw_sprite_stretched_ext(THEME.textbox, 0, _x, _y, _w, hh, boxColor, 0.5 + 0.5 * interactable); display_text(tx, _y + ui(7), _text, _w - ui(4)); } diff --git a/scripts/textBox/textBox.gml b/scripts/textBox/textBox.gml index 6e02c208b..262f08b52 100644 --- a/scripts/textBox/textBox.gml +++ b/scripts/textBox/textBox.gml @@ -526,7 +526,7 @@ function textBox(_input, _onModify, _extras = noone) : textInput(_input, _onModi if(hide) draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, _h, boxColor, 0.5); else - draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, _h, boxColor, 1.0); + draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, _h, boxColor, 0.5 + 0.5 * interactable); if(mouse_press(mb_left, active)) activate(); diff --git a/shaders/sh_morph_surface/sh_morph_surface.fsh b/shaders/sh_morph_surface/sh_morph_surface.fsh new file mode 100644 index 000000000..5991aef8c --- /dev/null +++ b/shaders/sh_morph_surface/sh_morph_surface.fsh @@ -0,0 +1,129 @@ +// +// Simple passthrough fragment shader +// +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform sampler2D sFrom; +uniform sampler2D sTo; +uniform vec2 dimension; +uniform float amount; +uniform float threshold; + +#define TAU 6.283185307179586 + +/////////////// SAMPLING /////////////// + +const float PI = 3.14159265358979323846; +uniform int interpolation; +uniform vec2 sampleDimension; + +const int RSIN_RADIUS = 1; + +float sinc ( float x ) { return x == 0.? 1. : sin(x * PI) / (x * PI); } + +vec4 texture2D_rsin( sampler2D texture, vec2 uv ) { + vec2 tx = 1.0 / sampleDimension; + vec2 p = uv * sampleDimension - vec2(0.5); + + vec4 sum = vec4(0.0); + float weights = 0.; + + for (int x = -RSIN_RADIUS; x <= RSIN_RADIUS; x++) + for (int y = -RSIN_RADIUS; y <= RSIN_RADIUS; y++) { + float a = length(vec2(float(x), float(y))) / float(RSIN_RADIUS); + if(a > 1.) continue; + float w = sinc(a * PI * tx.x) * sinc(a * PI * tx.y); + vec2 offset = vec2(float(x), float(y)) * tx; + vec4 sample = texture2D(texture, (p + offset + vec2(0.5)) / sampleDimension); + sum += w * sample; + weights += w; + } + + return sum / weights; +} + +vec4 texture2D_bicubic( sampler2D texture, vec2 uv ) { + uv = uv * sampleDimension + 0.5; + vec2 iuv = floor( uv ); + vec2 fuv = fract( uv ); + uv = iuv + fuv * fuv * (3.0 - 2.0 * fuv); + uv = (uv - 0.5) / sampleDimension; + return texture2D( texture, uv ); +} + +vec4 texture2Dintp( sampler2D texture, vec2 uv ) { + if(interpolation == 2) return texture2D_bicubic( texture, uv ); + else if(interpolation == 3) return texture2D_rsin( texture, uv ); + return texture2D( texture, uv ); +} + +/////////////// SAMPLING /////////////// + +void main() { + gl_FragColor = vec4(0.); + + //if(amount == 0.) { + // gl_FragColor = texture2Dintp( sFrom, v_vTexcoord ); + // return; + //} else if(amount == 1.) { + // gl_FragColor = texture2Dintp( sTo, v_vTexcoord ); + // return; + //} + + vec2 pxFrom, pxTo; + vec4 from, to; + float dist; + + for(float i = 0.; i <= dimension.x; i++) { + float base = 1.; + float top = 0.; + + if(amount > 0.5) + dist = i / dimension.x * (1. / amount); + else + dist = i / dimension.x * (1. / (1. - amount)); + + for(float j = 0.; j <= 64.; j++) { + float ang = top / base * TAU; + if(amount > 0.5) ang = TAU - ang; + + top += 2.; + if(top >= base) { + top = 1.; + base *= 2.; + } + + pxFrom = (vec2(cos(ang), sin(ang)) * i) / dimension; + vec2 xFrom = v_vTexcoord + pxFrom; + if(xFrom.x < 0. || xFrom.y < 0. || xFrom.x > 1. || xFrom.y > 1.) continue; + + vec2 vF = i == 0.? vec2(0.) : normalize(pxFrom); + + if(amount > 0.5) { + from = texture2Dintp( sFrom, xFrom ); + if(from.a == 0.) continue; + + pxTo = xFrom - (vF * dist); + if(pxTo.x < 0. || pxTo.y < 0. || pxTo.x > 1. || pxTo.y > 1.) continue; + + to = texture2Dintp( sTo, pxTo ); + if(to.a == 0.) continue; + } else { + to = texture2Dintp( sTo, xFrom ); + if(to.a == 0.) continue; + + pxTo = xFrom - (vF * dist); + if(pxTo.x < 0. || pxTo.y < 0. || pxTo.x > 1. || pxTo.y > 1.) continue; + + from = texture2Dintp( sFrom, pxTo ); + if(from.a == 0.) continue; + } + + if(distance(from, to) <= threshold * 2.) { + gl_FragColor = mix(from, to, amount); + return; + } + } + } +} diff --git a/shaders/sh_morph_surface/sh_morph_surface.vsh b/shaders/sh_morph_surface/sh_morph_surface.vsh new file mode 100644 index 000000000..d4b316559 --- /dev/null +++ b/shaders/sh_morph_surface/sh_morph_surface.vsh @@ -0,0 +1,18 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() { + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_morph_surface/sh_morph_surface.yy b/shaders/sh_morph_surface/sh_morph_surface.yy new file mode 100644 index 000000000..059f9dd69 --- /dev/null +++ b/shaders/sh_morph_surface/sh_morph_surface.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_morph_surface", + "parent": { + "name": "morph", + "path": "folders/shader/morph.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/sprites/s_node_morph_surface/3f1a7d2b-2007-4c49-be21-12931e1667df.png b/sprites/s_node_morph_surface/3f1a7d2b-2007-4c49-be21-12931e1667df.png new file mode 100644 index 0000000000000000000000000000000000000000..62f01ee1028556407f16c1dd4765fb0c767e8513 GIT binary patch literal 1428 zcmZ{keKga17{I^gt+wmsN+u&Oci!##<#i#X5p%tBDA5)Zvdp|r%u=D;@*0J_-OWok zONHAQCY|KvC<&ADdb8HjSzJ^~cl~qExqoz?^E{t(p67hd^T%_}bJ5rPumW5I4ggT_ zaL4&e==?o*$VuwWn1opgbRyjSy#Poz0Dy5GfX|W^;|&1G5CCrp0N7mv07*R4qQzMfu(siRho`VfnJJor>MClcB2FN6 z_pB%iHY&}P^NzINmSKDo^?J9?dQD$(k^+B6qV!O_;6LL*BuXcA4m`GT?g+3@V8<+8)N*JvUi%@rjeExAhUuQ4V|m2n&ys>dmE5tTe|awnECZ z$}x7e3$l^xH(qsns{p;^vtyKpja}YVqvwzpPQ$F{hvIdGGEas7;AYz8xK2)|G?|JF z;x+8qZA^$zS`4WhymmmhI_^~9S+t;~DD+7_9?3|PcND^9dC6hZ8$+@>!l~oPPpf>r zKIpC)YP^l2Dc|4v<%!v`&BW}K7V6jHi&9MdFECAn40ia;&;J&=RnY zEk6o6R`Mv0Opw~JSAt69|%qeCCw=I*A>YC#@D769YoU5hL}W*PCPKL>}nS4JA)JkqEYJCQ;mj%dQynCr(`&IfF)=LJmE|pNfzY>sqCzY*Kml z++RPS(?_BNS!ADrGQ!0s>*^Kj^VM>Vg9W>&wziwS*BaKBZms4Jsi}!IXuuG~dW9ij zg!+K>`!H@z5Igg>VfUEDSY@miIs1Nw^Qmf=gq#uGc59BZtaD`$@6HYMrh1L3xvI0D zaVn!=e2D*ZHcNdy&D$>${|?uXyM|W>PNc87aq=uFaS*{RxDZnZF5x)=fkU(tqqdJ~ z2aIfrBB-vc43OcYBTzRurlv!t>Y|k^Sdz;tscwG~EuS1n=q&;BO-BPvbz)NabHa%) z7Y2J|c2$%hrVU+1DsQ>$$w16*ka4KE+QhUEHH`r(SUB?O`Wm`93D8Zk_@>SWYf8)! zn7Oc(*`~a8ygt>O^_cY+g8|RW*FYVAq3x~!vXCe9Ki(T<#d>9KvCIR;WwTc|Kbn|r zI6XQwPi}AMXxNR{2igxhm5AoqOY0s?ThC@$Wl+?Q(uSv9uPRsc&3fqB-)_L^p%5(8Ob_SpnN`|T{Tc94ZB z1ld7Q@%bbD{}agZkug!U9}7#<3t1Au=)Vm~F=SF=5|K>#vC}rftCcvw!_^zdb|GZ{ E3;MHX(f|Me literal 0 HcmV?d00001 diff --git a/sprites/s_node_morph_surface/layers/3f1a7d2b-2007-4c49-be21-12931e1667df/cca573c2-d140-461a-8851-7fa9d2325537.png b/sprites/s_node_morph_surface/layers/3f1a7d2b-2007-4c49-be21-12931e1667df/cca573c2-d140-461a-8851-7fa9d2325537.png new file mode 100644 index 0000000000000000000000000000000000000000..62f01ee1028556407f16c1dd4765fb0c767e8513 GIT binary patch literal 1428 zcmZ{keKga17{I^gt+wmsN+u&Oci!##<#i#X5p%tBDA5)Zvdp|r%u=D;@*0J_-OWok zONHAQCY|KvC<&ADdb8HjSzJ^~cl~qExqoz?^E{t(p67hd^T%_}bJ5rPumW5I4ggT_ zaL4&e==?o*$VuwWn1opgbRyjSy#Poz0Dy5GfX|W^;|&1G5CCrp0N7mv07*R4qQzMfu(siRho`VfnJJor>MClcB2FN6 z_pB%iHY&}P^NzINmSKDo^?J9?dQD$(k^+B6qV!O_;6LL*BuXcA4m`GT?g+3@V8<+8)N*JvUi%@rjeExAhUuQ4V|m2n&ys>dmE5tTe|awnECZ z$}x7e3$l^xH(qsns{p;^vtyKpja}YVqvwzpPQ$F{hvIdGGEas7;AYz8xK2)|G?|JF z;x+8qZA^$zS`4WhymmmhI_^~9S+t;~DD+7_9?3|PcND^9dC6hZ8$+@>!l~oPPpf>r zKIpC)YP^l2Dc|4v<%!v`&BW}K7V6jHi&9MdFECAn40ia;&;J&=RnY zEk6o6R`Mv0Opw~JSAt69|%qeCCw=I*A>YC#@D769YoU5hL}W*PCPKL>}nS4JA)JkqEYJCQ;mj%dQynCr(`&IfF)=LJmE|pNfzY>sqCzY*Kml z++RPS(?_BNS!ADrGQ!0s>*^Kj^VM>Vg9W>&wziwS*BaKBZms4Jsi}!IXuuG~dW9ij zg!+K>`!H@z5Igg>VfUEDSY@miIs1Nw^Qmf=gq#uGc59BZtaD`$@6HYMrh1L3xvI0D zaVn!=e2D*ZHcNdy&D$>${|?uXyM|W>PNc87aq=uFaS*{RxDZnZF5x)=fkU(tqqdJ~ z2aIfrBB-vc43OcYBTzRurlv!t>Y|k^Sdz;tscwG~EuS1n=q&;BO-BPvbz)NabHa%) z7Y2J|c2$%hrVU+1DsQ>$$w16*ka4KE+QhUEHH`r(SUB?O`Wm`93D8Zk_@>SWYf8)! zn7Oc(*`~a8ygt>O^_cY+g8|RW*FYVAq3x~!vXCe9Ki(T<#d>9KvCIR;WwTc|Kbn|r zI6XQwPi}AMXxNR{2igxhm5AoqOY0s?ThC@$Wl+?Q(uSv9uPRsc&3fqB-)_L^p%5(8Ob_SpnN`|T{Tc94ZB z1ld7Q@%bbD{}agZkug!U9}7#<3t1Au=)Vm~F=SF=5|K>#vC}rftCcvw!_^zdb|GZ{ E3;MHX(f|Me literal 0 HcmV?d00001 diff --git a/sprites/s_node_morph_surface/s_node_morph_surface.yy b/sprites/s_node_morph_surface/s_node_morph_surface.yy new file mode 100644 index 000000000..53a1ae434 --- /dev/null +++ b/sprites/s_node_morph_surface/s_node_morph_surface.yy @@ -0,0 +1,74 @@ +{ + "resourceType": "GMSprite", + "resourceVersion": "1.0", + "name": "s_node_morph_surface", + "bbox_bottom": 61, + "bbox_left": 1, + "bbox_right": 61, + "bbox_top": 1, + "bboxMode": 0, + "collisionKind": 1, + "collisionTolerance": 0, + "DynamicTexturePage": false, + "edgeFiltering": false, + "For3D": false, + "frames": [ + {"resourceType":"GMSpriteFrame","resourceVersion":"1.1","name":"3f1a7d2b-2007-4c49-be21-12931e1667df",}, + ], + "gridX": 0, + "gridY": 0, + "height": 64, + "HTile": false, + "layers": [ + {"resourceType":"GMImageLayer","resourceVersion":"1.0","name":"cca573c2-d140-461a-8851-7fa9d2325537","blendMode":0,"displayName":"default","isLocked":false,"opacity":100.0,"visible":true,}, + ], + "nineSlice": null, + "origin": 4, + "parent": { + "name": "filter", + "path": "folders/nodes/icons/filter.yy", + }, + "preMultiplyAlpha": false, + "sequence": { + "resourceType": "GMSequence", + "resourceVersion": "1.4", + "name": "s_node_morph_surface", + "autoRecord": true, + "backdropHeight": 768, + "backdropImageOpacity": 0.5, + "backdropImagePath": "", + "backdropWidth": 1366, + "backdropXOffset": 0.0, + "backdropYOffset": 0.0, + "events": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "eventStubScript": null, + "eventToFunction": {}, + "length": 1.0, + "lockOrigin": false, + "moments": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "playback": 1, + "playbackSpeed": 30.0, + "playbackSpeedType": 0, + "showBackdrop": true, + "showBackdropImage": false, + "timeUnits": 1, + "tracks": [ + {"resourceType":"GMSpriteFramesTrack","resourceVersion":"1.0","name":"frames","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[ + {"resourceType":"Keyframe","resourceVersion":"1.0","Channels":{"0":{"resourceType":"SpriteFrameKeyframe","resourceVersion":"1.0","Id":{"name":"3f1a7d2b-2007-4c49-be21-12931e1667df","path":"sprites/s_node_morph_surface/s_node_morph_surface.yy",},},},"Disabled":false,"id":"757c3be6-712d-40c6-8d8f-588dc24562f8","IsCreationKey":false,"Key":0.0,"Length":1.0,"Stretch":false,}, + ],},"modifiers":[],"spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange": null, + "volume": 1.0, + "xorigin": 32, + "yorigin": 32, + }, + "swatchColours": null, + "swfPrecision": 2.525, + "textureGroupId": { + "name": "Default", + "path": "texturegroups/Default", + }, + "type": 0, + "VTile": false, + "width": 64, +} \ No newline at end of file