diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 5a212fe26..71acc2f50 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -90,7 +90,7 @@ {"name":"d3d particle","order":19,"path":"folders/nodes/data/3D/d3d particle.yy",}, {"name":"animation","order":6,"path":"folders/nodes/data/animation.yy",}, {"name":"compose","order":11,"path":"folders/nodes/data/compose.yy",}, - {"name":"armature","order":5,"path":"folders/nodes/data/compose/armature.yy",}, + {"name":"armature","order":3,"path":"folders/nodes/data/compose/armature.yy",}, {"name":"dynasurf","order":14,"path":"folders/nodes/data/dynasurf.yy",}, {"name":"filter","order":2,"path":"folders/nodes/data/filter.yy",}, {"name":"colors","order":4,"path":"folders/nodes/data/filter/colors.yy",}, @@ -694,6 +694,7 @@ {"name":"libxprocess","order":4,"path":"extensions/libxprocess/libxprocess.yy",}, {"name":"fd_rectangle_get_pressure_height","order":16,"path":"scripts/fd_rectangle_get_pressure_height/fd_rectangle_get_pressure_height.yy",}, {"name":"hyperbolic_function","order":16,"path":"scripts/hyperbolic_function/hyperbolic_function.yy",}, + {"name":"node_tile","order":4,"path":"scripts/node_tile/node_tile.yy",}, {"name":"sh_rsh_rotate","order":1,"path":"shaders/sh_rsh_rotate/sh_rsh_rotate.yy",}, {"name":"node_VFX_effect_destroy","order":3,"path":"scripts/node_VFX_effect_destroy/node_VFX_effect_destroy.yy",}, {"name":"node_cache","order":9,"path":"scripts/node_cache/node_cache.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index b91ae7439..799d57f3f 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1318,6 +1318,7 @@ {"id":{"name":"fd_rectangle_get_pressure_height","path":"scripts/fd_rectangle_get_pressure_height/fd_rectangle_get_pressure_height.yy",},}, {"id":{"name":"hyperbolic_function","path":"scripts/hyperbolic_function/hyperbolic_function.yy",},}, {"id":{"name":"s_node_fluidSim_repulse","path":"sprites/s_node_fluidSim_repulse/s_node_fluidSim_repulse.yy",},}, + {"id":{"name":"node_tile","path":"scripts/node_tile/node_tile.yy",},}, {"id":{"name":"sh_rsh_rotate","path":"shaders/sh_rsh_rotate/sh_rsh_rotate.yy",},}, {"id":{"name":"node_VFX_effect_destroy","path":"scripts/node_VFX_effect_destroy/node_VFX_effect_destroy.yy",},}, {"id":{"name":"node_cache","path":"scripts/node_cache/node_cache.yy",},}, diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index aa2197e80..1ff7170f2 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -36,6 +36,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor inputs[| 13] = nodeValue("Animation speed", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1 ); + inputs[| 14] = nodeValue("Use background dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true ); + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); frame_renderer_x = 0; @@ -148,12 +150,14 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor ["Output", false], 0, frame_renderer, 12, 13, ["Brush", false], 6, 2, 1, 11, ["Fill", false], 3, 4, - ["Display", false], 8, 10, 9, + ["Display", false], 8, 10, 14, 9, ]; attributes.frames = 1; attribute_surface_depth(); + attributes.dimension = [ 1, 1 ]; + output_surface = [ surface_create_empty(1, 1) ]; canvas_surface = [ surface_create_empty(1, 1) ]; canvas_buffer = [ buffer_create(1 * 1 * 4, buffer_fixed, 2) ]; @@ -276,7 +280,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } #endregion function apply_surface(index = preview_index) { #region - var _dim = getInputData(0); + var _dim = attributes.dimension; var cDep = attrDepth(); var _canvas_surface = getCanvasSurface(index); @@ -596,7 +600,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor mouse_cur_x = round((_mx - _x) / _s - 0.5); mouse_cur_y = round((_my - _y) / _s - 0.5); - var _dim = getInputData(0); + var _dim = attributes.dimension; var _col = getInputData(1); var _siz = getInputData(2); var _thr = getInputData(3); @@ -1010,10 +1014,14 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _bgr = getInputData(10); var _anim = getInputData(12); var _anims = getInputData(13); + var _bgDim = getInputData(14); var cDep = attrDepth(); apply_surfaces(); + if(_bgDim && is_surface(_bg)) _dim = [ surface_get_width_safe(_bg), surface_get_height_safe(_bg) ]; + attributes.dimension = _dim; + var _frames = attributes.frames; if(!is_array(output_surface)) output_surface = array_create(_frames); @@ -1041,7 +1049,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_surface_stretched_ext(_bg, 0, 0, _dim[0], _dim[1], c_white, _bga); draw_surface_safe(_canvas_surface, 0, 0); surface_reset_shader(); - } if(_anim) { @@ -1067,7 +1074,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } #endregion static doApplyDeserialize = function() { #region - var _dim = getInputData(0); + var _dim = struct_has(attributes, "dimension")? attributes.dimension : getInputData(0); if(!struct_has(load_map, "surfaces")) { if(struct_has(load_map, "surface")) { diff --git a/scripts/node_keyframe/node_keyframe.gml b/scripts/node_keyframe/node_keyframe.gml index b0dd66668..17608ca4a 100644 --- a/scripts/node_keyframe/node_keyframe.gml +++ b/scripts/node_keyframe/node_keyframe.gml @@ -280,28 +280,31 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { return _val; } #endregion - static setKeyTime = function(_key, _time, _replace = true) { #region + static setKeyTime = function(_key, _time, _replace = true, record = false) { #region if(!ds_list_exist(values, _key)) return 0; + if(_key.time == _time) return 0; + if(!LOADING) PROJECT.modified = true; _time = max(_time, 0); _key.setTime(_time); ds_list_remove(values, _key); - if(_replace) { - for( var i = 0; i < ds_list_size(values); i++ ) { - if(values[| i].time == _time) { - values[| i] = _key; - return 2; - } - } + if(_replace) + for( var i = 0; i < ds_list_size(values); i++ ) { + if(values[| i].time != _time) continue; + + if(record) recordAction(ACTION_TYPE.list_modify, values, [ values[| i], i ]); + values[| i] = _key; + return 2; } for( var i = 0; i < ds_list_size(values); i++ ) { - if(values[| i].time > _time) { - ds_list_insert(values, i, _key); - return 1; - } + if(values[| i].time < _time) continue; + + if(record) recordAction(ACTION_TYPE.list_insert, values, [ _key, i ]); + ds_list_insert(values, i, _key); + return 1; } ds_list_add(values, _key); diff --git a/scripts/node_particle/node_particle.gml b/scripts/node_particle/node_particle.gml index 5cc37b82e..598616890 100644 --- a/scripts/node_particle/node_particle.gml +++ b/scripts/node_particle/node_particle.gml @@ -111,7 +111,5 @@ function Node_Particle(_x, _y, _group = noone) : Node_VFX_Spawner_Base(_x, _y, _ //print($"Cache frame {CURRENT_FRAME}"); cacheCurrentFrame(_outSurf); } - } #endregion - - + } #endregion } \ No newline at end of file diff --git a/scripts/node_tile/node_outline.yy b/scripts/node_tile/node_outline.yy new file mode 100644 index 000000000..86468bc09 --- /dev/null +++ b/scripts/node_tile/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_tile/node_tile.gml b/scripts/node_tile/node_tile.gml new file mode 100644 index 000000000..60d30f1e8 --- /dev/null +++ b/scripts/node_tile/node_tile.gml @@ -0,0 +1,15 @@ +function Node_Tile(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Tile"; + + inputs[| 0] = nodeValue("Base texture", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Border texture", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + outputs[| 0] = nodeValue("", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, 0); + + input_display_list = [ 0 ]; + + static step = function() {} + + static processData = function(_outSurf, _data, _output_index, _array_index = 0) { return _outSurf; } +} \ No newline at end of file diff --git a/scripts/node_tile/node_tile.yy b/scripts/node_tile/node_tile.yy new file mode 100644 index 000000000..e91b011d6 --- /dev/null +++ b/scripts/node_tile/node_tile.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_tile", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "compose", + "path": "folders/nodes/data/compose.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 60aff9c43..e29778f92 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -593,14 +593,14 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru #endregion #region ---- draw ---- - draw_line_shift_x = 0; - draw_line_shift_y = 0; - draw_line_thick = 1; - draw_line_shift_hover = false; - draw_line_blend = 1; - drawLineIndex = 1; - draw_line_vb = noone; - draw_junction_index = type; + draw_line_shift_x = 0; + draw_line_shift_y = 0; + draw_line_thick = 1; + draw_line_shift_hover = false; + draw_line_blend = 1; + drawLineIndex = 1; + draw_line_vb = noone; + draw_junction_index = type; junction_drawing = [ THEME.node_junctions_single, type ]; @@ -1559,11 +1559,25 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static setAnim = function(anim) { #region if(is_anim == anim) return; - - if(anim && !is_anim && ds_list_size(animator.values) == 1) - animator.values[| 0].time = CURRENT_FRAME; - is_anim = anim; + + if(is_anim) { + animator.values[| 0].time = CURRENT_FRAME; + + for( var i = 0, n = array_length(animators); i < n; i++ ) { + ds_list_clear(animators[i].values); + animators[i].values[| 0].time = CURRENT_FRAME; + } + } else { + ds_list_clear(animator.values); + animator.values[| 0] = new valueKey(0, animator.getValue(), animator); + + for( var i = 0, n = array_length(animators); i < n; i++ ) { + ds_list_clear(animators[i].values); + animators[i].values[| 0] = new valueKey(0, animators[i].getValue(), animators[i]); + } + } + node.refreshTimeline(); } #endregion @@ -2355,6 +2369,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru var _map = {}; _map.visible = visible; + _map.color = color; if(connect_type == JUNCTION_CONNECT.output) return _map; @@ -2386,12 +2401,10 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru var _anims = []; for( var i = 0, n = array_length(animators); i < n; i++ ) array_push(_anims, animators[i].serialize(scale)); - _map.animators = _anims; + _map.animators = _anims; _map.display_data = display_data; _map.attributes = attributes; - - _map.name_custom = name_custom; - _map.color = color; + _map.name_custom = name_custom; return _map; } #endregion @@ -2402,6 +2415,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru if(!is_struct(_map)) return; visible = struct_try_get(_map, "visible", visible); + color = struct_try_get(_map, "color", -1); + if(connect_type == JUNCTION_CONNECT.output) return; @@ -2421,7 +2436,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru name_custom = struct_try_get(_map, "name_custom", false); if(name_custom) name = struct_try_get(_map, "name", name); - color = struct_try_get(_map, "color", -1); animator.deserialize(struct_try_get(_map, "raw_value"), scale); diff --git a/scripts/panel_animation/panel_animation.gml b/scripts/panel_animation/panel_animation.gml index e69e97927..954702886 100644 --- a/scripts/panel_animation/panel_animation.gml +++ b/scripts/panel_animation/panel_animation.gml @@ -361,7 +361,7 @@ function Panel_Animation() : PanelContent() constructor { for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { var k = keyframe_selecting[i]; - k.anim.setKeyTime(k, tt); + k.anim.setKeyTime(k, tt,, true); } } #endregion @@ -370,13 +370,17 @@ function Panel_Animation() : PanelContent() constructor { } #endregion function staggerKeys(_index, _stag) { #region + var modified = false; var t = keyframe_selecting[_index].time; + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { var k = keyframe_selecting[i]; var _t = t + abs(i - _index) * _stag; - k.anim.setKeyTime(k, _t); + modified |= k.anim.setKeyTime(k, _t); } + + if(modified) UNDO_HOLDING = true; } #endregion function onFocusBegin() { PANEL_ANIMATION = self; } @@ -512,7 +516,7 @@ function Panel_Animation() : PanelContent() constructor { #region bg draw_sprite_stretched(THEME.ui_panel_bg, 1, 0, 0, bar_w, bar_h); var __w = timeline_shift + TOTAL_FRAMES * ui(timeline_scale) + PANEL_PAD; - draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, min(__w, timeline_w), bar_h, COLORS.panel_animation_timeline_blend, 1); + draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, min(__w, timeline_w) - 1, bar_h, COLORS.panel_animation_timeline_blend, 1); if(inspecting) inspecting.drawAnimationTimeline(timeline_shift, bar_w, bar_h, timeline_scale); @@ -529,7 +533,7 @@ function Panel_Animation() : PanelContent() constructor { var bar_line_x = (CURRENT_FRAME + 1) * ui(timeline_scale) + timeline_shift; var cc = PROJECT.animator.is_playing? COLORS._main_value_positive : COLORS._main_accent; draw_set_color(cc); - draw_line(bar_line_x, ui(12), bar_line_x, bar_h - PANEL_PAD); + draw_line(bar_line_x, ui(15), bar_line_x, bar_h - PANEL_PAD); draw_set_text(f_p2, fa_center, fa_bottom, cc); draw_text_add(bar_line_x, ui(16), string(CURRENT_FRAME + 1)); @@ -1320,7 +1324,7 @@ function Panel_Animation() : PanelContent() constructor { var bar_show_w = timeline_shift + bar_total_w; var _bg_w = min(bar_total_w + PANEL_PAD, bar_w); - draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, _bg_w, dope_sheet_h, COLORS.panel_animation_timeline_blend, 1); + draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, _bg_w - 1, dope_sheet_h, COLORS.panel_animation_timeline_blend, 1); dope_sheet_y_max = 0; var key_y = ui(22) + dope_sheet_y; @@ -1395,6 +1399,7 @@ function Panel_Animation() : PanelContent() constructor { for(var i = timeline_sep_line; i <= TOTAL_FRAMES; i += timeline_sep_line) { var bar_line_x = i * ui(timeline_scale) + timeline_shift; + draw_set_color(COLORS.panel_animation_frame_divider); draw_set_alpha(i % timeline_separate == 0? 1 : 0.1); draw_line(bar_line_x, ui(16), bar_line_x, dope_sheet_h - PANEL_PAD); @@ -1484,23 +1489,28 @@ function Panel_Animation() : PanelContent() constructor { var tt = round((mx - bar_x - timeline_shift) / ui(timeline_scale)) - 1; tt = max(tt, 0); var sh = tt - keyframe_dragging.time; - + var edited = false; + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { var k = keyframe_selecting[i]; var kt = k.time + sh; - k.anim.setKeyTime(k, kt, false); + if(k.anim.setKeyTime(k, kt, false, true)) + edited = true; } - - timeline_show_time = floor(tt); + + if(edited) UNDO_HOLDING = true; + timeline_show_time = floor(tt); if(mouse_release(mb_left) || mouse_press(mb_left)) { keyframe_dragging = noone; - + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { var k = keyframe_selecting[i]; - k.anim.setKeyTime(k, k.time); + k.anim.setKeyTime(k, k.time, true, true); } + + UNDO_HOLDING = false; } } else { var dx = abs((keyframe_dragging.time + 1) - (mx - bar_x - timeline_shift) / ui(timeline_scale)) / 2; @@ -1556,6 +1566,7 @@ function Panel_Animation() : PanelContent() constructor { recordAction(ACTION_TYPE.var_modify, keyframe_dragging, [_ot, "ease_out"]); keyframe_dragging = noone; + UNDO_HOLDING = false; } } } @@ -1707,6 +1718,7 @@ function Panel_Animation() : PanelContent() constructor { } } else if(stagger_mode == 2) { stagger_mode = 0; + UNDO_HOLDING = false; } else if(key_hover == noone && keyframe_boxable) { keyframe_boxing = true; keyframe_box_sx = msx; @@ -1735,8 +1747,12 @@ function Panel_Animation() : PanelContent() constructor { for(var i = timeline_separate; i <= TOTAL_FRAMES; i += timeline_separate) { var bar_line_x = i * ui(timeline_scale) + timeline_shift; + + draw_set_color(COLORS.panel_animation_frame_divider); + draw_line(bar_line_x, 0, bar_line_x, ui(20)); + draw_set_text(f_p2, fa_right, fa_top, COLORS._main_text_sub); - draw_text_add(bar_line_x - ui(2), PANEL_PAD, string(i)); + draw_text_add(bar_line_x - ui(2), PANEL_PAD, i); } if(PROJECT.onion_skin.enabled) { //ONION SKIN @@ -1928,18 +1944,14 @@ function Panel_Animation() : PanelContent() constructor { if(by < ui(28)) return; by = ui(8); + var txt = __txt("New folder"); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(24), [mx, my], pFOCUS, pHOVER, txt, THEME.folder_content) == 2) { + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.folder_content) == 2) { var _dir = new timelineItemGroup(); PROJECT.timelines.addItem(_dir); } - //by += ui(28); - //var txt = show_node_outside_context? __txtx("panel_animation_hide_node", "Hide node outside context") : __txtx("panel_animation_show_node", "Show node outside context"); - //if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(24), [mx, my], pFOCUS, pHOVER, txt, THEME.junc_visible, show_node_outside_context) == 2) - // show_node_outside_context = !show_node_outside_context; - - by += ui(28); + by += ui(32); var txt = ""; switch(node_name_type) { case 0 : txt = __txtx("panel_animation_name_full", "Show full name"); break; @@ -1947,17 +1959,17 @@ function Panel_Animation() : PanelContent() constructor { case 2 : txt = __txtx("panel_animation_name_only", "Show node name"); break; } - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(24), [mx, my], pFOCUS, pHOVER, txt, THEME.node_name_type, node_name_type) == 2) + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.node_name_type, node_name_type) == 2) node_name_type = (node_name_type + 1) % 3; - by += ui(28); + by += ui(32); txt = __txtx("panel_animation_keyframe_override", "Override Keyframe"); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(24), [mx, my], pFOCUS, pHOVER, txt, THEME.keyframe_override, global.FLAG.keyframe_override) == 2) + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.keyframe_override, global.FLAG.keyframe_override) == 2) global.FLAG.keyframe_override = !global.FLAG.keyframe_override; - by += ui(28); + by += ui(32); txt = __txt("Onion skin"); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(24), [mx, my], pFOCUS, pHOVER, txt, THEME.onion_skin,, PROJECT.onion_skin.enabled? c_white : COLORS._main_icon) == 2) + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.onion_skin,, PROJECT.onion_skin.enabled? c_white : COLORS._main_icon) == 2) PROJECT.onion_skin.enabled = !PROJECT.onion_skin.enabled; } #endregion