diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 93397710f..d24bb675a 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -995,6 +995,7 @@ {"name":"node_path_map","order":19,"path":"scripts/node_path_map/node_path_map.yy",}, {"name":"node_path_plot","order":14,"path":"scripts/node_path_plot/node_path_plot.yy",}, {"name":"node_path_profile","order":10,"path":"scripts/node_path_profile/node_path_profile.yy",}, + {"name":"node_path_repeat","order":22,"path":"scripts/node_path_repeat/node_path_repeat.yy",}, {"name":"node_path_reverse","order":10,"path":"scripts/node_path_reverse/node_path_reverse.yy",}, {"name":"node_path_sample","order":6,"path":"scripts/node_path_sample/node_path_sample.yy",}, {"name":"node_path_scatter","order":21,"path":"scripts/node_path_scatter/node_path_scatter.yy",}, @@ -1093,7 +1094,7 @@ {"name":"node_scale","order":8,"path":"scripts/node_scale/node_scale.yy",}, {"name":"node_scatter_points","order":7,"path":"scripts/node_scatter_points/node_scatter_points.yy",}, {"name":"node_scatter","order":10,"path":"scripts/node_scatter/node_scatter.yy",}, - {"name":"node_segment_filter","order":22,"path":"scripts/node_segment_filter/node_segment_filter.yy",}, + {"name":"node_segment_filter","order":23,"path":"scripts/node_segment_filter/node_segment_filter.yy",}, {"name":"node_sequence_anim","order":5,"path":"scripts/node_sequence_anim/node_sequence_anim.yy",}, {"name":"node_shadow_cast","order":15,"path":"scripts/node_shadow_cast/node_shadow_cast.yy",}, {"name":"node_shadow","order":14,"path":"scripts/node_shadow/node_shadow.yy",}, @@ -1197,6 +1198,7 @@ {"name":"node_value_enum_button","order":7,"path":"scripts/node_value_enum_button/node_value_enum_button.yy",}, {"name":"node_value_enum_scroll","order":8,"path":"scripts/node_value_enum_scroll/node_value_enum_scroll.yy",}, {"name":"node_value_fdomain","order":8,"path":"scripts/node_value_fdomain/node_value_fdomain.yy",}, + {"name":"node_value_float","order":1,"path":"scripts/node_value_float/node_value_float.yy",}, {"name":"node_value_gradient","order":1,"path":"scripts/node_value_gradient/node_value_gradient.yy",}, {"name":"node_value_int","order":2,"path":"scripts/node_value_int/node_value_int.yy",}, {"name":"node_value_mesh","order":5,"path":"scripts/node_value_mesh/node_value_mesh.yy",}, @@ -2248,7 +2250,6 @@ {"name":"s_node_feedback_output","order":9,"path":"sprites/s_node_feedback_output/s_node_feedback_output.yy",}, {"name":"s_node_feedback","order":3,"path":"sprites/s_node_feedback/s_node_feedback.yy",}, {"name":"s_node_FFT","order":5,"path":"sprites/s_node_FFT/s_node_FFT.yy",}, - {"name":"node_value_float","order":1,"path":"scripts/node_value_float/node_value_float.yy",}, {"name":"s_node_filter_array","order":28,"path":"sprites/s_node_filter_array/s_node_filter_array.yy",}, {"name":"s_node_flip_render","order":10,"path":"sprites/s_node_flip_render/s_node_flip_render.yy",}, {"name":"s_node_flip","order":12,"path":"sprites/s_node_flip/s_node_flip.yy",}, @@ -2427,6 +2428,7 @@ {"name":"s_node_path_map","order":9,"path":"sprites/s_node_path_map/s_node_path_map.yy",}, {"name":"s_node_path_mapp","order":10,"path":"sprites/s_node_path_mapp/s_node_path_mapp.yy",}, {"name":"s_node_path_plot","order":11,"path":"sprites/s_node_path_plot/s_node_path_plot.yy",}, + {"name":"s_node_path_repeat","order":23,"path":"sprites/s_node_path_repeat/s_node_path_repeat.yy",}, {"name":"s_node_path_reverse","order":12,"path":"sprites/s_node_path_reverse/s_node_path_reverse.yy",}, {"name":"s_node_path_sample","order":13,"path":"sprites/s_node_path_sample/s_node_path_sample.yy",}, {"name":"s_node_path_scatter","order":19,"path":"sprites/s_node_path_scatter/s_node_path_scatter.yy",}, @@ -2740,6 +2742,7 @@ {"name":"s_search","order":182,"path":"sprites/s_search/s_search.yy",}, {"name":"s_sequence_control","order":185,"path":"sprites/s_sequence_control/s_sequence_control.yy",}, {"name":"s_shadow_drop_down_24","order":22,"path":"sprites/s_shadow_drop_down_24/s_shadow_drop_down_24.yy",}, + {"name":"s_shape_curve","order":35,"path":"sprites/s_shape_curve/s_shape_curve.yy",}, {"name":"s_slider","order":186,"path":"sprites/s_slider/s_slider.yy",}, {"name":"s_smoke_sim","order":187,"path":"sprites/s_smoke_sim/s_smoke_sim.yy",}, {"name":"s_sort_16","order":188,"path":"sprites/s_sort_16/s_sort_16.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 2aaad8530..4222db09b 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1533,6 +1533,7 @@ {"id":{"name":"node_path_map","path":"scripts/node_path_map/node_path_map.yy",},}, {"id":{"name":"node_path_plot","path":"scripts/node_path_plot/node_path_plot.yy",},}, {"id":{"name":"node_path_profile","path":"scripts/node_path_profile/node_path_profile.yy",},}, + {"id":{"name":"node_path_repeat","path":"scripts/node_path_repeat/node_path_repeat.yy",},}, {"id":{"name":"node_path_reverse","path":"scripts/node_path_reverse/node_path_reverse.yy",},}, {"id":{"name":"node_path_sample","path":"scripts/node_path_sample/node_path_sample.yy",},}, {"id":{"name":"node_path_scatter","path":"scripts/node_path_scatter/node_path_scatter.yy",},}, @@ -3120,6 +3121,7 @@ {"id":{"name":"s_node_path_map","path":"sprites/s_node_path_map/s_node_path_map.yy",},}, {"id":{"name":"s_node_path_mapp","path":"sprites/s_node_path_mapp/s_node_path_mapp.yy",},}, {"id":{"name":"s_node_path_plot","path":"sprites/s_node_path_plot/s_node_path_plot.yy",},}, + {"id":{"name":"s_node_path_repeat","path":"sprites/s_node_path_repeat/s_node_path_repeat.yy",},}, {"id":{"name":"s_node_path_reverse","path":"sprites/s_node_path_reverse/s_node_path_reverse.yy",},}, {"id":{"name":"s_node_path_sample","path":"sprites/s_node_path_sample/s_node_path_sample.yy",},}, {"id":{"name":"s_node_path_scatter","path":"sprites/s_node_path_scatter/s_node_path_scatter.yy",},}, @@ -3441,6 +3443,7 @@ {"id":{"name":"s_search","path":"sprites/s_search/s_search.yy",},}, {"id":{"name":"s_sequence_control","path":"sprites/s_sequence_control/s_sequence_control.yy",},}, {"id":{"name":"s_shadow_drop_down_24","path":"sprites/s_shadow_drop_down_24/s_shadow_drop_down_24.yy",},}, + {"id":{"name":"s_shape_curve","path":"sprites/s_shape_curve/s_shape_curve.yy",},}, {"id":{"name":"s_slider","path":"sprites/s_slider/s_slider.yy",},}, {"id":{"name":"s_smoke_sim","path":"sprites/s_smoke_sim/s_smoke_sim.yy",},}, {"id":{"name":"s_sort_16","path":"sprites/s_sort_16/s_sort_16.yy",},}, diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 26b2075a8..3df193b47 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -44,7 +44,7 @@ LATEST_VERSION = 1_18_00_0; VERSION = 1_18_05_1; SAVE_VERSION = 1_18_05_0; - VERSION_STRING = MAC? "1.18.003m" : "1.18.6.010"; + VERSION_STRING = MAC? "1.18.003m" : "1.18.6.011"; BUILD_NUMBER = 1_18_05_6; var _vsp = string_split(VERSION_STRING, "."); diff --git a/scripts/node_blur_zoom/node_blur_zoom.gml b/scripts/node_blur_zoom/node_blur_zoom.gml index bfee6afee..38706ccd4 100644 --- a/scripts/node_blur_zoom/node_blur_zoom.gml +++ b/scripts/node_blur_zoom/node_blur_zoom.gml @@ -7,7 +7,7 @@ function Node_Blur_Zoom(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) .setMappable(12); newInput(2, nodeValue_Vec2("Center", self, [ 0.5, 0.5 ])) - .setUnitRef(function(index) { return getDimension(index); }); + .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(3, nodeValue_Enum_Scroll("Oversample mode", self, 0, [ "Empty", "Clamp", "Repeat" ])) .setTooltip("How to deal with pixel outside the surface.\n - Empty: Use empty pixel\n - Clamp: Repeat edge pixel\n - Repeat: Repeat texture."); diff --git a/scripts/node_path_repeat/node_path_repeat.gml b/scripts/node_path_repeat/node_path_repeat.gml new file mode 100644 index 000000000..5072f5f85 --- /dev/null +++ b/scripts/node_path_repeat/node_path_repeat.gml @@ -0,0 +1,154 @@ +function Node_Path_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Repeat Path"; + setDimension(96, 48); + + newInput(0, nodeValue_PathNode("Path", self, noone)) + .setVisible(true, true); + + newInput(1, nodeValue_Int("Amount", self, 4)); + + newInput(2, nodeValue_Vec2("Shift Position", self, [ 0, 0 ])) + .setUnitRef(function() /*=>*/ {return DEF_SURF}, VALUE_UNIT.reference); + + newInput(3, nodeValue_Rotation("Shift Rotation", self, 0)); + + newInput(4, nodeValue_Vec2("Shift Scale", self, [ 1, 1 ])); + + newInput(5, nodeValue_Vec2("Anchor", self, [ 0, 0 ])) + .setUnitRef(function() /*=>*/ {return DEF_SURF}, VALUE_UNIT.reference); + + newOutput(0, nodeValue_Output("Path", self, VALUE_TYPE.pathnode, self)); + + input_display_list = [ + ["Paths", false], 0, 1, + ["Position", false], 2, + ["Rotation", false], 3, 5, + ["Scale", false], 4, + ]; + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var _path = getSingleValue(0); + if(_path && struct_has(_path, "drawOverlay")) _path.drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + + var _pos = getSingleValue(2); + var _px = _x + _pos[0] * _s; + var _py = _y + _pos[1] * _s; + + var _hv = inputs[2].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); hover &= !_hv; + var _hv = inputs[3].drawOverlay(hover, active, _px, _py, _s, _mx, _my, _snx, _sny); hover &= !_hv; + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + function Path_Repeat(_path) constructor { + line_amount = 0; + path = _path; + paths = []; + segment_counts = []; + line_lengths = []; + accu_lengths = []; + + __temp_p = [ 0, 0 ]; + + static getLineCount = function() /*=>*/ {return line_amount}; + static getSegmentCount = function(i=0) /*=>*/ {return array_safe_get_fast(segment_counts, i)}; + static getLength = function(i=0) /*=>*/ {return array_safe_get_fast(line_lengths, i)}; + static getAccuLength = function(i=0) /*=>*/ {return array_safe_get_fast(accu_lengths, i)}; + + static getPointRatio = function(_rat, ind = 0, out = undefined) { + if(out == undefined) out = new __vec2(); + + var _path = array_safe_get_fast(paths, ind, 0); + if(_path == 0) return out; + + if(!is_struct(path) || !struct_has(path, "getPointRatio")) + return out; + + var _ind = _path.index; + var _ori = _path.ori; + var _pos = _path.pos; + var _rot = _path.rot; + var _sca = _path.sca; + + out = path.getPointRatio(_rat, _ind, out); + + var _px = out.x - _ori[0]; + var _py = out.y - _ori[1]; + + __temp_p = point_rotate(_px, _py, 0, 0, _rot, __temp_p); + + out.x = _ori[0] + _pos[0] + __temp_p[0] * _sca[0]; + out.y = _ori[1] + _pos[1] + __temp_p[1] * _sca[1]; + + return out; + } + + static getPointDistance = function(_dist, ind = 0, out = undefined) { return getPointRatio(_dist / getLength(ind), ind, out); } + static getBoundary = function(ind = 0) { + var _path = getInputData(0); + return struct_has(_path, "getBoundary")? _path.getBoundary(ind) : new BoundingBox( 0, 0, 1, 1 ); + } + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + static update = function() { + var path = inputs[0].getValue(); + var amo = inputs[1].getValue(); + var pos = inputs[2].getValue(); + var rot = inputs[3].getValue(); + var sca = inputs[4].getValue(); + var anc = inputs[5].getValue(); + + var _repeat = new Path_Repeat(path); + outputs[0].setValue(_repeat); + + if(path == noone) return; + + var _line_amounts = path.getLineCount(); + _repeat.line_amount = amo * _line_amounts; + _repeat.paths = array_create(_repeat.line_amount); + _repeat.segment_counts = array_create(_repeat.line_amount); + _repeat.line_lengths = array_create(_repeat.line_amount); + _repeat.accu_lengths = array_create(_repeat.line_amount); + + var _px = pos[0]; + var _py = pos[1]; + var _sx = sca[0]; + var _sy = sca[1]; + var _ind = 0; + + for (var i = 0; i < amo; i++) { + var _pos = [ _px * i, _py * i ]; + var _rot = rot * i; + var _sca = [ power(_sx, i), power(_sy, i) ]; + var _ori = anc; + + for (var k = 0; k < _line_amounts; k++) { + _repeat.paths[_ind] = { + index : k, + ori : _ori, + pos : _pos, + rot : _rot, + sca : _sca, + } + + var _segment_counts = array_clone(path.getSegmentCount(k)); + var _line_lengths = array_clone(path.getLength(k)); + var _accu_lengths = array_clone(path.getAccuLength(k)); + + _repeat.segment_counts[_ind] = _segment_counts; + _repeat.line_lengths[_ind] = _line_lengths; + _repeat.accu_lengths[_ind] = _accu_lengths; + + _ind++; + } + } + + } + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + draw_sprite_fit(s_node_path_repeat, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); + } +} \ No newline at end of file diff --git a/scripts/node_path_repeat/node_path_repeat.yy b/scripts/node_path_repeat/node_path_repeat.yy new file mode 100644 index 000000000..b5579fdde --- /dev/null +++ b/scripts/node_path_repeat/node_path_repeat.yy @@ -0,0 +1,14 @@ +{ + "$GMScript":"v1", + "%Name":"node_path_repeat", + "isCompatibility":false, + "isDnD":false, + "name":"node_path_repeat", + "parent":{ + "name":"path", + "path":"folders/nodes/data/value/path.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", + "tags":[], +} \ No newline at end of file diff --git a/scripts/node_path_scatter/node_path_scatter.gml b/scripts/node_path_scatter/node_path_scatter.gml index 4f740834a..8982ee73b 100644 --- a/scripts/node_path_scatter/node_path_scatter.gml +++ b/scripts/node_path_scatter/node_path_scatter.gml @@ -61,10 +61,11 @@ function Node_Path_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro __temp_p = [ 0, 0 ]; - static getLineCount = function() { return line_amount; } - static getSegmentCount = function(ind = 0) { return array_safe_get_fast(segment_counts, ind); } - static getLength = function(ind = 0) { return array_safe_get_fast(line_lengths, ind); } - static getAccuLength = function(ind = 0) { return array_safe_get_fast(accu_lengths, ind); } + static getLineCount = function() /*=>*/ {return line_amount}; + static getSegmentCount = function(i=0) /*=>*/ {return array_safe_get_fast(segment_counts, i)}; + static getLength = function(i=0) /*=>*/ {return array_safe_get_fast(line_lengths, i)}; + static getAccuLength = function(i=0) /*=>*/ {return array_safe_get_fast(accu_lengths, i)}; + static getPointRatio = function(_rat, ind = 0, out = undefined) { if(out == undefined) out = new __vec2(); else { out.x = 0; out.y = 0; } @@ -129,19 +130,17 @@ function Node_Path_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro var _scattered = new Path_Scatter(); if(path_base == noone) return _scattered; if(path_scat == noone) return _scattered; - var p = new __vec2(); - - random_set_seed(_seed); var _line_amounts = path_scat.getLineCount(); - var _ind = 0; - _scattered.line_amount = _repeat * _line_amounts; _scattered.paths = array_create(_scattered.line_amount); _scattered.segment_counts = array_create(_scattered.line_amount); _scattered.line_lengths = array_create(_scattered.line_amount); _scattered.accu_lengths = array_create(_scattered.line_amount); + random_set_seed(_seed); + var _ind = 0; + var p = new __vec2(); var ori, pos; var _prog_raw, _prog; var _dir, _sca, _rot, _rotW, _trm; diff --git a/scripts/node_path_shape/node_path_shape.gml b/scripts/node_path_shape/node_path_shape.gml index 740993915..ba8aed9e5 100644 --- a/scripts/node_path_shape/node_path_shape.gml +++ b/scripts/node_path_shape/node_path_shape.gml @@ -21,6 +21,9 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc -1, new scrollItem("Polygon", s_node_shape_type, 12), new scrollItem("Star", s_node_shape_type, 13), + -1, + new scrollItem("Line", s_node_shape_type, 16), + new scrollItem("Curve", s_shape_curve, 0), ]; newInput(3, nodeValue_Enum_Scroll("Shape", self, 0, shapeScroll)); @@ -49,6 +52,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc boundary = new BoundingBox(); cached_pos = ds_map_create(); + loop = true; shape = 0; posx = 0; posy = 0; scax = 1; scay = 1; @@ -58,6 +62,8 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc pa2x = 0; pa2y = 0; pa3 = 0; + preview_surf = noone; + static getLineCount = function() /*=>*/ {return 1}; static getSegmentCount = function() /*=>*/ {return array_length(lengths)}; static getBoundary = function() /*=>*/ {return boundary}; @@ -98,7 +104,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Arc" : - var a = lerp_angle(pa2x, pa2y, _rat); + var a = lerp_float_angle(pa2x, pa2y, _rat); out.x = posx + lengthdir_x(scax, a); out.y = posy + lengthdir_y(scay, a); break; @@ -112,7 +118,10 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Polygon" : - case "Star" : return getPointDistance(_rat * lengthTotal, _ind, out); + case "Star" : + case "Line" : + case "Curve" : + return getPointDistance(_rat * lengthTotal, _ind, out); } @@ -161,7 +170,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc oy = ny; } - draw_line(ox, oy, x0, y0); + if(loop) draw_line(ox, oy, x0, y0); var _px = _x + posx * _s; var _py = _y + posy * _s; @@ -204,6 +213,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc switch(shapeScroll[shape].name) { case "Rectangle" : + loop = true; points = [ [ posx - scax, posy - scay ], [ posx + scax, posy - scay ], @@ -213,6 +223,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Trapezoid" : + loop = true; inputs[4].setVisible(true); points = [ @@ -224,6 +235,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Parallelogram" : + loop = true; inputs[4].setVisible(true); points = [ @@ -235,6 +247,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Ellipse" : + loop = true; var _st = 64; var _as = 360 / _st; points = array_create(_st); @@ -247,14 +260,15 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Arc" : + loop = false; inputs[5].setVisible(true); var _st = 64; - var _as = 1 / (_st - 63); + var _as = 1 / (_st - 1); points = array_create(_st); for( var i = 0; i < _st; i++ ) { - var a = lerp_angle(_aran[0], _aran[1], i * _as); + var a = lerp_float_angle(_aran[0], _aran[1], i * _as); nx = posx + lengthdir_x(scax, a); ny = posy + lengthdir_y(scay, a); points[i] = [ nx, ny ]; @@ -262,6 +276,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Squircle" : + loop = true; inputs[6].setVisible(true); var _st = 64; @@ -279,6 +294,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Polygon" : + loop = true; inputs[7].setVisible(true); var _st = _sid; @@ -293,6 +309,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc break; case "Star" : + loop = true; inputs[7].setVisible(true); inputs[8].setVisible(true); @@ -311,10 +328,36 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc } break; + case "Line": + loop = false; + points = [ + [ posx - scax, posy ], + [ posx + scax, posy ], + ]; + break; + + case "Curve": + loop = false; + inputs[6].setVisible(true); + + var _st = 64; + var _as = 180 / (_st - 1); + var _x0 = posx - scax; + var _x1 = posx + scax; + var _yy = posy; + + points = array_create(_st); + for( var i = 0; i < _st; i++ ) { + points[i] = [ + lerp(_x0, _x1, i / (_st - 1)), + _yy + dsin(i * _as) * pa3, + ] + } + break; } var n = array_length(points); - lengths = array_create(n + 1); + lengths = array_create(n + loop); if(n) { for( var i = 0; i < n; i++ ) { @@ -328,7 +371,7 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc oy = ny; } - lengths[n - 1] = point_distance(ox, oy, x0, y0); + if(loop) lengths[n - 1] = point_distance(ox, oy, x0, y0); } var _len = array_length(lengths); @@ -341,10 +384,40 @@ function Node_Path_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) construc } boundary = new BoundingBox(posx - scax, posy - scay, posx + scax, posy + scay); + + preview_surf = surface_verify(preview_surf, 128, 128); + surface_set_target(preview_surf); + DRAW_CLEAR + + var ox, x0; + var oy, y0; + var nx, ny; + var xx = posx - scax; + var yy = posy - scay; + var ww = scax * 2; + var hh = scay * 2; + draw_set_color(COLORS._main_accent); + + if(array_length(points)) { + for( var i = 0, n = array_length(points); i < n; i++ ) { + nx = 4 + (points[i][0] - xx) / ww * 120; + ny = 4 + (points[i][1] - yy) / hh * 120; + + if(i) draw_line_width(ox, oy, nx, ny, 8); + else { x0 = nx; y0 = ny; } + + ox = nx; + oy = ny; + } + + if(loop) draw_line_width(ox, oy, x0, y0, 8); + } + surface_reset_target(); } static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { var bbox = drawGetBbox(xx, yy, _s); + draw_surface_bbox(preview_surf, bbox); } static getPreviewBoundingBox = function() { return BBOX().fromBoundingBox(boundary); } diff --git a/scripts/node_path_transform/node_path_transform.gml b/scripts/node_path_transform/node_path_transform.gml index 105a2cd39..67472c257 100644 --- a/scripts/node_path_transform/node_path_transform.gml +++ b/scripts/node_path_transform/node_path_transform.gml @@ -16,15 +16,16 @@ function Node_Path_Transform(_x, _y, _group = noone) : Node(_x, _y, _group) cons newOutput(0, nodeValue_Output("Path", self, VALUE_TYPE.pathnode, self)); cached_pos = ds_map_create(); + path = noone; + pos = [ 0, 0 ]; + rot = 0; + sca = [ 1, 1 ]; + anc = [ 0, 0 ]; static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { - var pth = getInputData(0); - var pos = getInputData(4); var px = _x + pos[0] * _s; var py = _y + pos[1] * _s; - // if(pth) pth.drawOverlay(-1, false, _x, _y, _s, _mx, _my, _snx, _sny); - active &= !inputs[1].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); active &= !inputs[2].drawOverlay(hover, active, px, py, _s, _mx, _my, _snx, _sny); @@ -32,34 +33,28 @@ function Node_Path_Transform(_x, _y, _group = noone) : Node(_x, _y, _group) cons active &= !inputs[4].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, 1); } - static getLineCount = function() { var _path = getInputData(0); return struct_has(_path, "getLineCount")? _path.getLineCount() : 1; } - static getSegmentCount = function(ind = 0) { var _path = getInputData(0); return struct_has(_path, "getSegmentCount")? _path.getSegmentCount(ind) : 0; } - static getLength = function(ind = 0) { var _path = getInputData(0); return struct_has(_path, "getLength")? _path.getLength(ind) : 0; } - static getAccuLength = function(ind = 0) { var _path = getInputData(0); return struct_has(_path, "getAccuLength")? _path.getAccuLength(ind) : []; } + static getLineCount = function() { return struct_has(path, "getLineCount")? path.getLineCount() : 1; } + static getSegmentCount = function(ind = 0) { return struct_has(path, "getSegmentCount")? path.getSegmentCount(ind) : 0; } + static getLength = function(ind = 0) { return struct_has(path, "getLength")? path.getLength(ind) : 0; } + static getAccuLength = function(ind = 0) { return struct_has(path, "getAccuLength")? path.getAccuLength(ind) : []; } static getBoundary = function(ind = 0) { - var _path = getInputData(0); - if(!struct_has(_path, "getBoundary")) + if(!struct_has(path, "getBoundary")) return new BoundingBox( 0, 0, 1, 1 ); - var b = _path.getBoundary(ind).clone(); + var b = path.getBoundary(ind).clone(); - var _pos = getInputData(1); - var _rot = getInputData(2); - var _sca = getInputData(3); - var _anc = getInputData(4); + b.minx = _anc[0] + (b.minx - _anc[0]) * sca[0]; + b.miny = _anc[1] + (b.miny - _anc[1]) * sca[1]; + var _pp = point_rotate(b.minx, b.miny, _anc[0], _anc[1], rot); + b.minx = _pp[0] + pos[0]; + b.miny = _pp[1] + pos[1]; - b.minx = _anc[0] + (b.minx - _anc[0]) * _sca[0]; - b.miny = _anc[1] + (b.miny - _anc[1]) * _sca[1]; - var _pp = point_rotate(b.minx, b.miny, _anc[0], _anc[1], _rot); - b.minx = _pp[0] + _pos[0]; - b.miny = _pp[1] + _pos[1]; - - b.maxx = _anc[0] + (b.maxx - _anc[0]) * _sca[0]; - b.maxy = _anc[1] + (b.maxy - _anc[1]) * _sca[1]; - var _pp = point_rotate(b.maxx, b.maxy, _anc[0], _anc[1], _rot); - b.maxx = _pp[0] + _pos[0]; - b.maxy = _pp[1] + _pos[1]; + b.maxx = _anc[0] + (b.maxx - _anc[0]) * sca[0]; + b.maxy = _anc[1] + (b.maxy - _anc[1]) * sca[1]; + var _pp = point_rotate(b.maxx, b.maxy, _anc[0], _anc[1], rot); + b.maxx = _pp[0] + pos[0]; + b.maxy = _pp[1] + pos[1]; var _minx = min(b.minx, b.maxx); var _maxx = max(b.minx, b.maxx); @@ -80,29 +75,23 @@ function Node_Path_Transform(_x, _y, _group = noone) : Node(_x, _y, _group) cons return out; } - var _path = getInputData(0); - var _pos = getInputData(1); - var _rot = getInputData(2); - var _sca = getInputData(3); - var _anc = getInputData(4); - - if(is_array(_path)) { - _path = array_safe_get_fast(_path, ind); + if(is_array(path)) { + path = array_safe_get_fast(path, ind); ind = 0; } - if(!is_struct(_path) || !struct_has(_path, "getPointRatio")) + if(!is_struct(path) || !struct_has(path, "getPointRatio")) return out; - var _p = _path.getPointRatio(_rat, ind).clone(); + var _p = path.getPointRatio(_rat, ind).clone(); - _p.x = _anc[0] + (_p.x - _anc[0]) * _sca[0]; - _p.y = _anc[1] + (_p.y - _anc[1]) * _sca[1]; + _p.x = anc[0] + (_p.x - anc[0]) * sca[0]; + _p.y = anc[1] + (_p.y - anc[1]) * sca[1]; - var _pp = point_rotate(_p.x, _p.y, _anc[0], _anc[1], _rot); + var _pp = point_rotate(_p.x, _p.y, anc[0], anc[1], rot); - out.x = _pp[0] + _pos[0]; - out.y = _pp[1] + _pos[1]; + out.x = _pp[0] + pos[0]; + out.y = _pp[1] + pos[1]; cached_pos[? _cKey] = out.clone(); @@ -111,28 +100,15 @@ function Node_Path_Transform(_x, _y, _group = noone) : Node(_x, _y, _group) cons static getPointDistance = function(_dist, ind = 0, out = undefined) { return getPointRatio(_dist / getLength(), ind, out); } - static getBoundary = function(ind = 0) { - var _path = getInputData(0); - var _pos = getInputData(1); - var _rot = getInputData(2); - var _sca = getInputData(3); - - if(_path == noone) return [ 0, 0, 1, 1 ]; - - var _b = _path.getBoundary(ind); - - var cx = (_b[0] + _b[2]) / 2; - var cy = (_b[1] + _b[1]) / 2; - - _b[0] = cx + (_b[0] - cx) * _sca[0]; - _b[1] = cy + (_b[1] - cy) * _sca[1]; - _b[2] = cx + (_b[2] - cx) * _sca[0]; - _b[3] = cy + (_b[3] - cy) * _sca[1]; - } - static update = function() { ds_map_clear(cached_pos); outputs[0].setValue(self); + + path = getInputData(0); + pos = getInputData(1); + rot = getInputData(2); + sca = getInputData(3); + anc = getInputData(4); } static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { diff --git a/scripts/node_path_wave/node_path_wave.gml b/scripts/node_path_wave/node_path_wave.gml index 99a7c7c34..b04a8f404 100644 --- a/scripts/node_path_wave/node_path_wave.gml +++ b/scripts/node_path_wave/node_path_wave.gml @@ -23,11 +23,13 @@ function Node_Path_Wave(_x, _y, _group = noone) : Node(_x, _y, _group) construct newInput(9, nodeValue_Curve("Amplitude over length", self, CURVE_DEF_11)); + newInput(10, nodeValue_Enum_Button("Post Fn", self, 0, [ "None", "Absolute", "Clamp" ])); + newOutput(0, nodeValue_Output("Path", self, VALUE_TYPE.pathnode, self)); input_display_list = [ 5, ["Path", true], 0, - ["Wave", false], 1, 2, 9, 3, 4, + ["Wave", false], 1, 2, 9, 3, 4, 10, ["Wiggle", true, 6], 7, 8, ]; @@ -35,8 +37,9 @@ function Node_Path_Wave(_x, _y, _group = noone) : Node(_x, _y, _group) construct fre = 0; amp = 0; shf = 0; - mode = 0; seed = 0; + mode = 0; + post = 0; wig = 0 wigs = 0 @@ -164,6 +167,12 @@ function Node_Path_Wave(_x, _y, _group = noone) : Node(_x, _y, _group) construct case 2 : prg = (frac(_t) > .5) * 2 - 1; break; } + switch(post) { + case 0 : break; + case 1 : prg = abs(prg); break; + case 2 : prg = max(prg, 0); break; + } + if(amp_curve) prg *= amp_curve.get(_rat); out.x = p.x + lengthdir_x(_amp * prg, dir); @@ -196,6 +205,8 @@ function Node_Path_Wave(_x, _y, _group = noone) : Node(_x, _y, _group) construct var _ampc = getInputData(9); amp_curve = new curveMap(_ampc, 128); + post = getInputData(10); + outputs[0].setValue(self); } diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 6d7d61d04..8d97c42c6 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -704,11 +704,12 @@ function __initNodes() { var d3d = ds_list_create(); addNodeCatagory("3D", d3d); ds_list_add(d3d, "2D Operations"); - addNodeObject(d3d, "Normal", s_node_normal, "Node_Normal", [1, Node_Normal],, "Create normal map using greyscale value as height."); - addNodeObject(d3d, "Normal Light", s_node_normal_light, "Node_Normal_Light", [1, Node_Normal_Light],, "Light up the image using normal mapping."); - addNodeObject(d3d, "Bevel", s_node_bevel, "Node_Bevel", [1, Node_Bevel],, "Apply 2D bevel on the image."); - addNodeObject(d3d, "Sprite Stack", s_node_stack, "Node_Sprite_Stack", [1, Node_Sprite_Stack],, "Create sprite stack either from repeating a single image or stacking different images using array."); - addNodeObject(d3d, "Ambient Occlusion", s_node_AO, "Node_Ambient_Occlusion", [1, Node_Ambient_Occlusion], ["ao"], "Apply simple 2D AO effect using height map.").patreonExtra(); + addNodeObject(d3d, "Transform 3D", s_node_image_transform_3d, "Node_3D_Transform_Image", [1, Node_3D_Transform_Image], ["3d transform"], "Transform image in 3D space").setVersion(11600); + addNodeObject(d3d, "Normal", s_node_normal, "Node_Normal", [1, Node_Normal],, "Create normal map using greyscale value as height."); + addNodeObject(d3d, "Normal Light", s_node_normal_light, "Node_Normal_Light", [1, Node_Normal_Light],, "Light up the image using normal mapping."); + addNodeObject(d3d, "Bevel", s_node_bevel, "Node_Bevel", [1, Node_Bevel],, "Apply 2D bevel on the image."); + addNodeObject(d3d, "Sprite Stack", s_node_stack, "Node_Sprite_Stack", [1, Node_Sprite_Stack],, "Create sprite stack either from repeating a single image or stacking different images using array."); + addNodeObject(d3d, "Ambient Occlusion", s_node_AO, "Node_Ambient_Occlusion", [1, Node_Ambient_Occlusion], ["ao"], "Apply simple 2D AO effect using height map.").patreonExtra(); ds_list_add(d3d, "3D"); addNodeObject(d3d, "3D Camera", s_node_3d_camera, "Node_3D_Camera", [1, Node_3D_Camera],, "Create 3D camera that render scene to surface.").setVersion(11510); @@ -716,7 +717,6 @@ function __initNodes() { addNodeObject(d3d, "3D Material", s_node_3d_meterial, "Node_3D_Material", [1, Node_3D_Material],, "Create 3D material with adjustable parameters.").setVersion(11510); addNodeObject(d3d, "3D Scene", s_node_3d_scene, "Node_3D_Scene", [1, Node_3D_Scene],, "Combine multiple 3D objects into a single junction.").setVersion(11510); addNodeObject(d3d, "3D Repeat", s_node_3d_array, "Node_3D_Repeat", [1, Node_3D_Repeat],, "Repeat the same 3D mesh multiple times.").setVersion(11510); - addNodeObject(d3d, "Transform 3D", s_node_image_transform_3d, "Node_3D_Transform_Image", [1, Node_3D_Transform_Image], ["3d transform"], "Transform image in 3D space").setVersion(11600); addNodeObject(d3d, "Mesh Export", s_node_3d_obj_export, "Node_3D_Mesh_Export", [1, Node_3D_Mesh_Export],, "Export 3D mesh as .obj file").setVersion(11740); ds_list_add(d3d, "Mesh"); @@ -967,7 +967,7 @@ function __initNodes() { 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],, "Move rotate and scale a path.").setVersion(1130); + addNodeObject(values, "Transform Path", s_node_path_transform, "Node_Path_Transform", [1, Node_Path_Transform], ["path transform"], "Move rotate and scale a path.").setVersion(1130); addNodeObject(values, "Shift Path", s_node_path_shift, "Node_Path_Shift", [1, Node_Path_Shift],, "Move path along its normal.").setVersion(1130); addNodeObject(values, "Trim Path", s_node_path_trim, "Node_Path_Trim", [1, Node_Path_Trim],, "Trim path.").setVersion(1130); addNodeObject(values, "Wave Path", s_node_path_wave, "Node_Path_Wave", [1, Node_Path_Wave], ["zigzag path"], "Apply wave effect along the path.").setVersion(1130); @@ -980,6 +980,7 @@ function __initNodes() { addNodeObject(values, "Bake Path", s_node_path_bake, "Node_Path_Bake", [1, Node_Path_Bake],, "Bake path data into array of vec2 points.").setVersion(11640); addNodeObject(values, "Map Path", s_node_path_mapp, "Node_Path_Map", [1, Node_Path_Map],, "Map a texture between multiple paths.").setVersion(11640); addNodeObject(values, "Scatter Path", s_node_path_scatter, "Node_Path_Scatter", [1, Node_Path_Scatter],, "Scatter paths along another path.").setVersion(11740); + addNodeObject(values, "Repeat Path", s_node_path_repeat, "Node_Path_Repeat", [1, Node_Path_Repeat],, "Repeat paths.").setVersion(1_18_05_6); addNodeObject(values, "3D Path", s_node_path_3d, "Node_Path_3D", [1, Node_Path_3D], [ "path 3d" ], "Create path in 3D space.").setVersion(11750); addNodeObject(values, "Filter Segments",s_node_segment_filter, "Node_Segment_Filter", [1, Node_Segment_Filter],, "Filter segment (vec2 array) based on a conditions.").setVersion(11780); diff --git a/shaders/sh_blur_radial/sh_blur_radial.fsh b/shaders/sh_blur_radial/sh_blur_radial.fsh index 6cefc7456..5c0fd76c3 100644 --- a/shaders/sh_blur_radial/sh_blur_radial.fsh +++ b/shaders/sh_blur_radial/sh_blur_radial.fsh @@ -95,13 +95,12 @@ varying vec4 v_vColour; uniform vec2 center; uniform vec2 dimension; uniform int gamma; +uniform int iteration; uniform vec2 strength; uniform int strengthUseSurf; uniform sampler2D strengthSurf; -#define ITERATION 64. - void main() { float str = strength.x; float strMax = max(strength.x, strength.y); diff --git a/sprites/s_node_path_repeat/82ea1fbc-306e-4810-8663-7aa1281ecfb0.png b/sprites/s_node_path_repeat/82ea1fbc-306e-4810-8663-7aa1281ecfb0.png new file mode 100644 index 000000000..91fcd7200 Binary files /dev/null and b/sprites/s_node_path_repeat/82ea1fbc-306e-4810-8663-7aa1281ecfb0.png differ diff --git a/sprites/s_node_path_repeat/layers/82ea1fbc-306e-4810-8663-7aa1281ecfb0/828f8a8f-7837-4fc7-9c25-7a2c1640315e.png b/sprites/s_node_path_repeat/layers/82ea1fbc-306e-4810-8663-7aa1281ecfb0/828f8a8f-7837-4fc7-9c25-7a2c1640315e.png new file mode 100644 index 000000000..91fcd7200 Binary files /dev/null and b/sprites/s_node_path_repeat/layers/82ea1fbc-306e-4810-8663-7aa1281ecfb0/828f8a8f-7837-4fc7-9c25-7a2c1640315e.png differ diff --git a/sprites/s_node_path_repeat/s_node_path_repeat.yy b/sprites/s_node_path_repeat/s_node_path_repeat.yy new file mode 100644 index 000000000..6f4ef99f7 --- /dev/null +++ b/sprites/s_node_path_repeat/s_node_path_repeat.yy @@ -0,0 +1,90 @@ +{ + "$GMSprite":"", + "%Name":"s_node_path_repeat", + "bboxMode":0, + "bbox_bottom":62, + "bbox_left":5, + "bbox_right":59, + "bbox_top":4, + "collisionKind":1, + "collisionTolerance":0, + "DynamicTexturePage":false, + "edgeFiltering":false, + "For3D":false, + "frames":[ + {"$GMSpriteFrame":"","%Name":"82ea1fbc-306e-4810-8663-7aa1281ecfb0","name":"82ea1fbc-306e-4810-8663-7aa1281ecfb0","resourceType":"GMSpriteFrame","resourceVersion":"2.0",}, + ], + "gridX":0, + "gridY":0, + "height":64, + "HTile":false, + "layers":[ + {"$GMImageLayer":"","%Name":"828f8a8f-7837-4fc7-9c25-7a2c1640315e","blendMode":0,"displayName":"default","isLocked":false,"name":"828f8a8f-7837-4fc7-9c25-7a2c1640315e","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,}, + ], + "name":"s_node_path_repeat", + "nineSlice":null, + "origin":4, + "parent":{ + "name":"path", + "path":"folders/nodes/icons/value/path.yy", + }, + "preMultiplyAlpha":false, + "resourceType":"GMSprite", + "resourceVersion":"2.0", + "sequence":{ + "$GMSequence":"", + "%Name":"s_node_path_repeat", + "autoRecord":true, + "backdropHeight":768, + "backdropImageOpacity":0.5, + "backdropImagePath":"", + "backdropWidth":1366, + "backdropXOffset":0.0, + "backdropYOffset":0.0, + "events":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "eventStubScript":null, + "eventToFunction":{}, + "length":1.0, + "lockOrigin":false, + "moments":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "name":"s_node_path_repeat", + "playback":1, + "playbackSpeed":30.0, + "playbackSpeedType":0, + "resourceType":"GMSequence", + "resourceVersion":"2.0", + "showBackdrop":true, + "showBackdropImage":false, + "timeUnits":1, + "tracks":[ + {"$GMSpriteFramesTrack":"","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"$KeyframeStore":"","Keyframes":[ + {"$Keyframe":"","Channels":{ + "0":{"$SpriteFrameKeyframe":"","Id":{"name":"82ea1fbc-306e-4810-8663-7aa1281ecfb0","path":"sprites/s_node_path_repeat/s_node_path_repeat.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",}, + },"Disabled":false,"id":"dc913832-8bbd-473b-9390-5ac0496f3769","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe","resourceVersion":"2.0","Stretch":false,}, + ],"resourceType":"KeyframeStore","resourceVersion":"2.0",},"modifiers":[],"name":"frames","resourceType":"GMSpriteFramesTrack","resourceVersion":"2.0","spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange":null, + "volume":1.0, + "xorigin":32, + "yorigin":32, + }, + "swatchColours":null, + "swfPrecision":0.5, + "textureGroupId":{ + "name":"Default", + "path":"texturegroups/Default", + }, + "type":0, + "VTile":false, + "width":64, +} \ No newline at end of file diff --git a/sprites/s_shape_curve/3e4c10ef-18cc-480d-9d47-1e5536116b6f.png b/sprites/s_shape_curve/3e4c10ef-18cc-480d-9d47-1e5536116b6f.png new file mode 100644 index 000000000..212bb7b05 Binary files /dev/null and b/sprites/s_shape_curve/3e4c10ef-18cc-480d-9d47-1e5536116b6f.png differ diff --git a/sprites/s_shape_curve/layers/3e4c10ef-18cc-480d-9d47-1e5536116b6f/380cae66-efcd-47c9-8f8d-c92366a4cd97.png b/sprites/s_shape_curve/layers/3e4c10ef-18cc-480d-9d47-1e5536116b6f/380cae66-efcd-47c9-8f8d-c92366a4cd97.png new file mode 100644 index 000000000..212bb7b05 Binary files /dev/null and b/sprites/s_shape_curve/layers/3e4c10ef-18cc-480d-9d47-1e5536116b6f/380cae66-efcd-47c9-8f8d-c92366a4cd97.png differ diff --git a/sprites/s_shape_curve/s_shape_curve.yy b/sprites/s_shape_curve/s_shape_curve.yy new file mode 100644 index 000000000..1790db05b --- /dev/null +++ b/sprites/s_shape_curve/s_shape_curve.yy @@ -0,0 +1,90 @@ +{ + "$GMSprite":"", + "%Name":"s_shape_curve", + "bboxMode":0, + "bbox_bottom":20, + "bbox_left":3, + "bbox_right":20, + "bbox_top":3, + "collisionKind":1, + "collisionTolerance":0, + "DynamicTexturePage":false, + "edgeFiltering":false, + "For3D":false, + "frames":[ + {"$GMSpriteFrame":"","%Name":"3e4c10ef-18cc-480d-9d47-1e5536116b6f","name":"3e4c10ef-18cc-480d-9d47-1e5536116b6f","resourceType":"GMSpriteFrame","resourceVersion":"2.0",}, + ], + "gridX":0, + "gridY":0, + "height":24, + "HTile":false, + "layers":[ + {"$GMImageLayer":"","%Name":"380cae66-efcd-47c9-8f8d-c92366a4cd97","blendMode":0,"displayName":"default","isLocked":false,"name":"380cae66-efcd-47c9-8f8d-c92366a4cd97","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,}, + ], + "name":"s_shape_curve", + "nineSlice":null, + "origin":4, + "parent":{ + "name":"nodes", + "path":"folders/sprites/nodes.yy", + }, + "preMultiplyAlpha":false, + "resourceType":"GMSprite", + "resourceVersion":"2.0", + "sequence":{ + "$GMSequence":"", + "%Name":"s_shape_curve", + "autoRecord":true, + "backdropHeight":768, + "backdropImageOpacity":0.5, + "backdropImagePath":"", + "backdropWidth":1366, + "backdropXOffset":0.0, + "backdropYOffset":0.0, + "events":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "eventStubScript":null, + "eventToFunction":{}, + "length":1.0, + "lockOrigin":false, + "moments":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "name":"s_shape_curve", + "playback":1, + "playbackSpeed":30.0, + "playbackSpeedType":0, + "resourceType":"GMSequence", + "resourceVersion":"2.0", + "showBackdrop":true, + "showBackdropImage":false, + "timeUnits":1, + "tracks":[ + {"$GMSpriteFramesTrack":"","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"$KeyframeStore":"","Keyframes":[ + {"$Keyframe":"","Channels":{ + "0":{"$SpriteFrameKeyframe":"","Id":{"name":"3e4c10ef-18cc-480d-9d47-1e5536116b6f","path":"sprites/s_shape_curve/s_shape_curve.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",}, + },"Disabled":false,"id":"ab59fe78-342e-44e5-87e6-975c867d1406","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe","resourceVersion":"2.0","Stretch":false,}, + ],"resourceType":"KeyframeStore","resourceVersion":"2.0",},"modifiers":[],"name":"frames","resourceType":"GMSpriteFramesTrack","resourceVersion":"2.0","spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange":null, + "volume":1.0, + "xorigin":12, + "yorigin":12, + }, + "swatchColours":null, + "swfPrecision":0.5, + "textureGroupId":{ + "name":"Default", + "path":"texturegroups/Default", + }, + "type":0, + "VTile":false, + "width":24, +} \ No newline at end of file