From 574472b8a3e9b4a5b0a428f6d36bd86f62898a16 Mon Sep 17 00:00:00 2001 From: Tanasart Date: Mon, 1 Apr 2024 11:34:02 +0700 Subject: [PATCH] - [Animation Panel] Add button for hiding node label. --- scripts/node_collection/node_collection.gml | 110 ++++++------- scripts/node_data/node_data.gml | 152 ++++++++---------- scripts/node_keyframe/node_keyframe.gml | 83 ++++++---- .../node_seperate_shape.gml | 1 - scripts/node_value/node_value.gml | 41 +++-- scripts/panel_animation/panel_animation.gml | 81 +++++++--- 6 files changed, 262 insertions(+), 206 deletions(-) diff --git a/scripts/node_collection/node_collection.gml b/scripts/node_collection/node_collection.gml index d8430e47c..0f0a55cfc 100644 --- a/scripts/node_collection/node_collection.gml +++ b/scripts/node_collection/node_collection.gml @@ -138,7 +138,9 @@ function upgroupNode(collection, record = true) { #region } #endregion function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { - nodes = ds_list_create(); + nodes = ds_list_create(); + node_length = ds_list_size(nodes); + ungroupable = true; auto_render_time = false; combine_render_time = true; @@ -156,8 +158,6 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc attributes.input_display_list = []; attributes.output_display_list = []; - attributes.w = 128; - attributes.h = 128; managedRenderOrder = false; @@ -192,37 +192,45 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc array_push(attributeEditors, ["Edit Output Display", function() { return 0; }, button(function() { dialogCall(o_dialog_group_input_order).setNode(self, JUNCTION_CONNECT.output); }) ]); + hasInsp1 = false; insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node contents"); insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + hasInsp2 = false; insp2UpdateTooltip = "Clear cache"; insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ]; - static inspector1Update = function() { onInspector1Update(); } - static onInspector1Update = function() { RenderList(nodes, true); } - static hasInspector1Update = function(group = false) { #region - for( var i = 0; i < ds_list_size(nodes); i++ ) { - if(nodes[| i].hasInspector1Update()) - return true; - } - - return false; - } #endregion + static inspector1Update = function() { onInspector1Update(); } + static onInspector1Update = function() { RenderList(nodes, true); } + static hasInspector1Update = function() { INLINE return hasInsp1; } - static inspector2Update = function() { onInspector2Update(); } - static onInspector2Update = function() { #region - for( var i = 0; i < ds_list_size(nodes); i++ ) { + static inspector2Update = function() { onInspector2Update(); } + static onInspector2Update = function() { #region + var i = 0; + + repeat(node_length) { if(nodes[| i].hasInspector2Update()) nodes[| i].inspector2Update(); + i++; } } #endregion - static hasInspector2Update = function(group = false) { #region - for( var i = 0; i < ds_list_size(nodes); i++ ) { - if(nodes[| i].hasInspector2Update()) - return true; - } + static hasInspector2Update = function() { INLINE return hasInsp2; } + + will_refresh = false; + static refreshNodes = function() { #region + will_refresh = false; + node_length = ds_list_size(nodes); - return false; + hasInsp1 = false; + hasInsp2 = false; + + var i = 0; + repeat(node_length) { + hasInsp1 |= nodes[| i].hasInspector1Update(); + hasInsp2 |= nodes[| i].hasInspector2Update(); + + i++; + } } #endregion static getNodeBase = function() { #region @@ -236,23 +244,6 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc return instanceBase.getNodeList(); } #endregion - static setHeight = function() { #region - var _hi = ui(32); - var _ho = ui(32); - - for( var i = 0; i < ds_list_size(inputs); i++ ) - if(inputs[| i].isVisible()) _hi += 24; - if(active_draw_index == 1) _hi += 24; - draw_dummy = active_draw_index == 1; - - for( var i = 0; i < ds_list_size(outputs); i++ ) - if(outputs[| i].isVisible()) _ho += 24; - - var preH = (preview_surface && previewable)? 128 : 0; - - h = max(min_h, preH, _hi, _ho); - } #endregion - static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region if(!draw_input_overlay) return; @@ -267,17 +258,17 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc } #endregion static getOutputNodes = function() { #region - var nodes = []; + var _nodes = []; for( var i = custom_output_index; i < ds_list_size(outputs); i++ ) { var _junc = outputs[| i]; for( var j = 0; j < array_length(_junc.value_to); j++ ) { var _to = _junc.value_to[j]; if(_to.value_from != _junc) continue; - array_push_unique(nodes, _to.node); + array_push_unique(_nodes, _to.node); } } - return nodes; + return _nodes; } #endregion static getInput = function(junc = noone) { #region @@ -290,7 +281,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc LOG_BLOCK_START(); LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from group: {INAME}"); - var nodes = []; + var _nodes = []; if(isRenderActive()) { var allReady = true; for(var i = custom_input_index; i < ds_list_size(inputs); i++) { @@ -304,18 +295,18 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc } } - nodes = __nodeLeafList(getNodeList()); + _nodes = __nodeLeafList(getNodeList()); } LOG_BLOCK_END(); - return nodes; + return _nodes; } #endregion static getNextNodesExternal = function() { #region //get node connected to the parent object LOG_IF(global.FLAG.render == 1, $"Checking next node external for {INAME}"); LOG_BLOCK_START(); - var nodes = []; + var nextNodes = []; for( var i = 0; i < ds_list_size(outputs); i++ ) { var _ot = outputs[| i]; if(!_ot.forward) continue; @@ -329,12 +320,12 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc LOG_IF(global.FLAG.render == 1, $"Checking node {_node.internalName} : {_node.isRenderable()}"); if(!_node.isRenderable()) continue; - array_push(nodes, _to.node); + array_push(nextNodes, _to.node); } } LOG_BLOCK_END(); - return nodes; + return nextNodes; } #endregion static setRenderStatus = function(result) { #region @@ -379,6 +370,8 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc recordAction(ACTION_TYPE.group_added, self, _node); _node.group = self; + + will_refresh = true; } #endregion static remove = function(_node) { #region @@ -397,6 +390,8 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc nodeDelete(_node); else _node.group = group; + + will_refresh = true; } #endregion static clearCache = function() { #region @@ -406,7 +401,10 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc } } #endregion - static stepBegin = function() { doStepBegin(); } + static stepBegin = function() { + if(will_refresh) refreshNodes(); + doStepBegin(); + } static step = function() { #region if(combine_render_time) { @@ -416,8 +414,6 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc render_time += node_list[| i].render_time; } - w = attributes.w; - onStep(); } #endregion @@ -460,7 +456,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc } #endregion static getTool = function() { #region - for(var i = 0; i < ds_list_size(nodes); i++) { + for(var i = 0; i < node_length; i++) { var _node = nodes[| i]; if(_node.isTool) return _node.getTool(); } @@ -476,7 +472,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc var dups = ds_list_create(); - for(var i = 0; i < ds_list_size(nodes); i++) { + for(var i = 0; i < node_length; i++) { var _node = nodes[| i]; var _cnode = _node.clone(target); ds_list_add(dups, _cnode); @@ -514,7 +510,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc setRenderStatus(false); if(_clearCache) clearInputCache(); - for( var i = 0; i < ds_list_size(nodes); i++ ) + for( var i = 0; i < node_length; i++ ) nodes[| i].resetRender(_clearCache); } #endregion @@ -543,7 +539,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc static getGraphPreviewSurface = function() { #region var _output_junc = outputs[| preview_channel]; - for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) { + for( var i = 0, n = node_length; i < n; i++ ) { if(!nodes[| i].active) continue; if(is_instanceof(nodes[| i], Node_Group_Thumbnail)) _output_junc = nodes[| i].inputs[| 0]; @@ -562,12 +558,12 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc static enable = function() { #region active = true; timeline_item.active = true; - for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) nodes[| i].enable(); + for( var i = 0, n = node_length; i < n; i++ ) nodes[| i].enable(); } #endregion static disable = function() { #region active = false; timeline_item.active = false; - for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) nodes[| i].disable(); + for( var i = 0, n = node_length; i < n; i++ ) nodes[| i].disable(); } #endregion static processSerialize = function(_map) { #region diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 17821fc1b..ca241d040 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -1,6 +1,8 @@ global.loop_nodes = [ "Node_Iterate", "Node_Iterate_Each" ]; #macro INAME internalName == ""? name : internalName +#macro NODE_HAS_INSP1 (onInspector1Update != noone) +#macro NODE_HAS_INSP2 (onInspector2Update != noone) enum CACHE_USE { none, @@ -165,6 +167,23 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { outputs_amount = 0; outputs_index = []; out_cache_len = 0; + + input_buttons = []; + input_button_length = 0; + + run_in(1, function() { + input_buttons = []; + + for( var i = 0; i < ds_list_size(inputs); i++ ) { + var _in = inputs[| i]; + if(!is_instanceof(_in, NodeValue)) continue; + if(_in.type != VALUE_TYPE.trigger) continue; + + array_push(input_buttons, _in); + } + + input_button_length = array_length(input_buttons); + }); #endregion #region --- attributes ---- @@ -242,8 +261,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { #region ---- notification ---- value_validation = array_create(3); - error_noti_update = noone; - error_update_enabled = false; manual_updated = false; #endregion @@ -484,6 +501,11 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { return renamed? "[" + name + "] " + display_name : name; } #endregion + static getDisplayName = function() { #region + INLINE + return renamed? display_name : name; + } #endregion + static addInput = function(junctionFrom, shift = input_fix_len) { #region var targ = getInput(junctionFrom, shift); if(targ == noone) return; @@ -515,19 +537,13 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { } #endregion #region ++++ inspector update ++++ - static inspector1Update = function() { - if(error_update_enabled && error_noti_update != noone) - noti_remove(error_noti_update); - error_noti_update = noone; - - onInspector1Update(); - } - static onInspector1Update = noone; - static hasInspector1Update = function() { return onInspector1Update != noone; } + static onInspector1Update = noone; + static inspector1Update = function() { INLINE onInspector1Update(); } + static hasInspector1Update = function() { INLINE return NODE_HAS_INSP1; } - static inspector2Update = function() { onInspector2Update(); } - static onInspector2Update = noone; - static hasInspector2Update = function() { return onInspector2Update != noone; } + static onInspector2Update = noone; + static inspector2Update = function() { INLINE onInspector2Update(); } + static hasInspector2Update = function() { INLINE return NODE_HAS_INSP2; } #endregion static stepBegin = function() { #region @@ -535,8 +551,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { doStepBegin(); - if(hasInspector1Update()) inspectInput1.name = insp1UpdateTooltip; - if(hasInspector2Update()) inspectInput2.name = insp2UpdateTooltip; + if(NODE_HAS_INSP1) inspectInput1.name = insp1UpdateTooltip; + if(NODE_HAS_INSP2) inspectInput2.name = insp2UpdateTooltip; if(attributes.show_update_trigger) { if(updatedInTrigger.getValue()) { @@ -554,43 +570,33 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { } if(is_3D) USE_DEPTH = true; - if(is_simulation) PROJECT.animator.is_simulating = true; } #endregion static doStepBegin = function() {} - static triggerCheck = function() { _triggerCheck(); } - - static _triggerCheck = function() { #region - for( var i = 0; i < ds_list_size(inputs); i++ ) { - var _in = inputs[| i]; - if(!is_instanceof(_in, NodeValue)) continue; + static triggerCheck = function() { #region + var i = 0; + + repeat( input_button_length ) { + var _in = input_buttons[i]; - if(_in.type != VALUE_TYPE.trigger) continue; - if(!is_instanceof(_in.editWidget, buttonClass)) continue; - - var trig = _in.getValue(); - if(trig && !_in.display_data.output) { + if(_in.getStaticValue() && !_in.display_data.output) { _in.editWidget.onClick(); _in.setValue(false); } + + i++; } - if(hasInspector1Update()) { - var trig = inspectInput1.getValue(); - if(trig) { - onInspector1Update(); - inspectInput1.setValue(false); - } + if(NODE_HAS_INSP1 && inspectInput1.getStaticValue()) { + onInspector1Update(); + inspectInput1.setValue(false); } - if(hasInspector2Update()) { - var trig = inspectInput2.getValue(); - if(trig) { - onInspector2Update(); - inspectInput2.setValue(false); - } + if(NODE_HAS_INSP2 && inspectInput2.getStaticValue()) { + onInspector2Update(); + inspectInput2.setValue(false); } } #endregion @@ -616,7 +622,9 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { for(var i = 0; i < ds_list_size(inputs); i++) { if(!is_instanceof(inputs[| i], NodeValue)) continue; - setInputData(i, inputs[| i].getValue(frame,,, false)); + + var val = inputs[| i].getValue(frame,,, false); + setInputData(i, val); } } #endregion @@ -669,15 +677,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { } } - if(hasInspector1Update()) { - var trigger = inspectInput1.getValue(); - if(trigger) onInspector1Update(); - } - - if(hasInspector2Update()) { - var trigger = inspectInput2.getValue(); - if(trigger) onInspector2Update(); - } + if(NODE_HAS_INSP1 && inspectInput1.getValue()) onInspector1Update(); + if(NODE_HAS_INSP2 && inspectInput2.getValue()) onInspector2Update(); updatedOutTrigger.setValue(true); @@ -696,8 +697,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { } #endregion static valueUpdate = function(index) { #region - if(error_update_enabled && error_noti_update == noone) - error_noti_update = noti_error(getFullName() + " node require manual execution.",, self); onValueUpdate(index); @@ -957,15 +956,15 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { var yy = y * _s + _y; var jun; - var inspCount = hasInspector1Update() + hasInspector2Update(); + var inspCount = NODE_HAS_INSP1 + NODE_HAS_INSP2; var ind = 1; - if(hasInspector1Update()) { + if(NODE_HAS_INSP1) { inspectInput1.x = xx + w * _s * ind / (inspCount + 1); inspectInput1.y = yy; ind++; } - if(hasInspector2Update()) { + if(NODE_HAS_INSP2) { inspectInput2.x = xx + w * _s * ind / (inspCount + 1); inspectInput2.y = yy; ind++; @@ -1067,13 +1066,11 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { } #endregion static drawNodeName = function(xx, yy, _s) { #region - if(draw_graph_culled) return; - if(!active) return; draw_name = false; var _name = renamed? display_name : name; if(_name == "") return; - if(_s < 0.75) return; + draw_name = true; var aa = 0.25 + 0.5 * renderActive; @@ -1088,7 +1085,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { draw_set_text(f_p1, fa_left, fa_center, cc); - if(hasInspector1Update()) icon = THEME.refresh_16; + if(NODE_HAS_INSP1) icon = THEME.refresh_16; var ts = clamp(power(_s, 0.5), 0.5, 1); var aa = 0.5 + 0.5 * renderActive; @@ -1188,15 +1185,11 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { hover = jun; } - if(hasInspector1Update()) { - if(inspectInput1.drawJunction(_s, _mx, _my)) - hover = inspectInput1; - } + if(NODE_HAS_INSP1 && inspectInput1.drawJunction(_s, _mx, _my)) + hover = inspectInput1; - if(hasInspector2Update()) { - if(inspectInput2.drawJunction(_s, _mx, _my)) - hover = inspectInput2; - } + if(NODE_HAS_INSP2 && inspectInput2.drawJunction(_s, _mx, _my)) + hover = inspectInput2; if(attributes.show_update_trigger) { if(updatedInTrigger.drawJunction(_s, _mx, _my)) hover = updatedInTrigger; @@ -1230,15 +1223,11 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { hover = jun; } - if(hasInspector1Update()) { - if(inspectInput1.drawJunction_fast(_s, _mx, _my)) - hover = inspectInput1; - } + if(NODE_HAS_INSP1 && inspectInput1.drawJunction_fast(_s, _mx, _my)) + hover = inspectInput1; - if(hasInspector2Update()) { - if(inspectInput2.drawJunction_fast(_s, _mx, _my)) - hover = inspectInput2; - } + if(NODE_HAS_INSP2 && inspectInput2.drawJunction_fast(_s, _mx, _my)) + hover = inspectInput2; if(attributes.show_update_trigger) { if(updatedInTrigger.drawJunction_fast(_s, _mx, _my)) hover = updatedInTrigger; @@ -1286,12 +1275,12 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { outputs[| i].drawName(_s, _mx, _my); } - if(hasInspector1Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) { + if(NODE_HAS_INSP1 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) { inspectInput1.drawNameBG(_s); inspectInput1.drawName(_s, _mx, _my); } - if(hasInspector2Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) { + if(NODE_HAS_INSP2 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) { inspectInput2.drawNameBG(_s); inspectInput2.drawName(_s, _mx, _my); } @@ -1331,8 +1320,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { } var st = 0; - if(hasInspector1Update()) st = -1; - if(hasInspector2Update()) st = -2; + if(NODE_HAS_INSP1) st = -1; + if(NODE_HAS_INSP2) st = -2; var _inputs = array_create(ds_list_size(inputs)); var _len = 0; @@ -1519,7 +1508,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { preview_mx = _mx; preview_my = _my; - if(value_validation[VALIDATION.error] || error_noti_update != noone) + if(value_validation[VALIDATION.error]) draw_sprite_stretched_ext(THEME.node_glow_border, 0, xx - 9, yy - 9, w * _s + 18, h * _s + 18, COLORS._main_value_negative, 1); drawNodeBase(xx, yy, _s); @@ -1542,7 +1531,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { if(show_parameter) drawJunctionWidget(xx, yy, _mx, _my, _s, _hover, _focus); - drawNodeName(xx, yy, _s); + if(_s >= 0.75) + drawNodeName(xx, yy, _s); if(active_draw_index > -1) { draw_sprite_stretched_ext(bg_sel_spr, 0, xx, yy, round(w * _s), round(h * _s), active_draw_index > 1? COLORS.node_border_file_drop : COLORS._main_accent, 1); diff --git a/scripts/node_keyframe/node_keyframe.gml b/scripts/node_keyframe/node_keyframe.gml index e03676ce0..bb9138c9e 100644 --- a/scripts/node_keyframe/node_keyframe.gml +++ b/scripts/node_keyframe/node_keyframe.gml @@ -92,6 +92,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { #region ---- main ---- suffix = ""; values = ds_list_create(); + length = 1; sep_axis = _sep_axis; index = 0; @@ -131,6 +132,8 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { } #endregion static updateKeyMap = function() { #region + length = ds_list_size(values); + if(!prop.is_anim && !LOADING && !APPENDING) return; if(ds_list_empty(values)) { @@ -256,8 +259,11 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { static getName = function() { return prop.name + suffix; } static getValue = function(_time = CURRENT_FRAME) { #region + + ///////////////////////////////////////////////////////////// TRIGGER TYPE ///////////////////////////////////////////////////////////// + if(prop.type == VALUE_TYPE.trigger) { - if(ds_list_size(values) == 0) + if(length == 0) return false; if(!prop.is_anim) @@ -274,8 +280,10 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { return _key.time == _time? _key.value : false; } - if(ds_list_size(values) == 0) return processTypeDefault(); - if(ds_list_size(values) == 1) { + ///////////////////////////////////////////////////////////// OPTIMIZATION ///////////////////////////////////////////////////////////// + + if(length == 0) return processTypeDefault(); + if(length == 1) { var _key = values[| 0]; if(_key.drivers.type && _time >= _key.time) @@ -286,14 +294,16 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { if(prop.type == VALUE_TYPE.path) return processType(values[| 0].value); if(!prop.is_anim) return processType(values[| 0].value); - var _len = max(TOTAL_FRAMES, values[| ds_list_size(values) - 1].time); + var _len = max(TOTAL_FRAMES, values[| length - 1].time); if(array_length(key_map) != _len) updateKeyMap(); - var _time_first = prop.loop_range == -1? values[| 0].time : values[| ds_list_size(values) - 1 - prop.loop_range].time; - var _time_last = values[| ds_list_size(values) - 1].time; + var _time_first = prop.loop_range == -1? values[| 0].time : values[| length - 1 - prop.loop_range].time; + var _time_last = values[| length - 1].time; var _time_dura = _time_last - _time_first; - if(_time > _time_last) { #region //loop time + ////////////////////////////////////////////////////////////// LOOP TIME /////////////////////////////////////////////////////////////// + + if(_time > _time_last) { switch(prop.on_end) { case KEYFRAME_END.loop : _time = _time_first + safe_mod(_time - _time_last, _time_dura + 1); @@ -306,16 +316,18 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { _time = _time_first + _time_dura * 2 - time_in_loop; break; } - } #endregion + } var _keyIndex; if(_time >= _len) _keyIndex = 999_999; else if(_time <= 0) _keyIndex = -1; else _keyIndex = array_safe_get_fast(key_map, _time); - if(_keyIndex == -1) { #region Before first key + //////////////////////////////////////////////////////////// BEFORE FIRST ////////////////////////////////////////////////////////////// + + if(_keyIndex == -1) { if(prop.on_end == KEYFRAME_END.wrap) { - var from = values[| ds_list_size(values) - 1]; + var from = values[| length - 1]; var to = values[| 0]; var fTime = from.time; @@ -331,10 +343,12 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { } return processType(values[| 0].value); //First frame - } #endregion + } - if(_keyIndex == 999_999) { #region After last key - var _lstKey = values[| ds_list_size(values) - 1]; + ///////////////////////////////////////////////////////////// AFTER LAST /////////////////////////////////////////////////////////////// + + if(_keyIndex == 999_999) { + var _lstKey = values[| length - 1]; if(_lstKey.drivers.type) return processType(processDriver(_time, _lstKey)); @@ -352,20 +366,21 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { } return processType(_lstKey.value); //Last frame - } #endregion + } - #region In between - var from = values[| _keyIndex]; - var to = values[| _keyIndex + 1]; + ///////////////////////////////////////////////////////////// INBETWEEN //////////////////////////////////////////////////////////////// + + var from = values[| _keyIndex]; + var to = values[| _keyIndex + 1]; - var rat = (_time - from.time) / (to.time - from.time); - var _lrp = interpolate(from, to, rat); + var rat = (_time - from.time) / (to.time - from.time); + var _lrp = interpolate(from, to, rat); - if(from.drivers.type) - return processDriver(_time, from, lerpValue(from, to, _lrp), rat); + if(from.drivers.type) + return processDriver(_time, from, lerpValue(from, to, _lrp), rat); - return lerpValue(from, to, _lrp); - #endregion + return lerpValue(from, to, _lrp); + } #endregion static processTypeDefault = function() { #region @@ -409,7 +424,10 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { } #endregion static processType = function(_val) { #region + INLINE + var _res = _val; + if(!sep_axis && typeArray(prop.display_type) && is_array(_val)) { for(var i = 0; i < array_length(_val); i++) _res[i] = processValue(_val[i]); @@ -420,22 +438,18 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { } #endregion static processValue = function(_val) { #region + INLINE + if(is_array(_val)) return _val; if(is_struct(_val)) return _val; - if(is_undefined(_val)) return 0; - - if(prop.type == VALUE_TYPE.integer && prop.unit.mode == VALUE_UNIT.constant) - return round(_val); + //if(is_undefined(_val)) return 0; switch(prop.type) { - case VALUE_TYPE.integer : + case VALUE_TYPE.integer : return prop.unit.mode == VALUE_UNIT.constant? round(_val) : _val; case VALUE_TYPE.float : return _val; - case VALUE_TYPE.text : return string_real(_val); - case VALUE_TYPE.color : return is_real(_val)? cola(_val) : _val; - case VALUE_TYPE.surface : - if(is_string(_val)) - return get_asset(_val); - return _val; + case VALUE_TYPE.text : return is_string(_val)? _val : string_real(_val); + case VALUE_TYPE.color : return is_real(_val)? cola(_val) : _val; + case VALUE_TYPE.surface : return is_string(_val)? get_asset(_val) : _val; } return _val; @@ -501,6 +515,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { } #endregion static setValue = function(_val = 0, _record = true, _time = CURRENT_FRAME, ease_in = 0, ease_out = 0) { #region + if(prop.type == VALUE_TYPE.trigger) { if(!prop.is_anim) { values[| 0] = new valueKey(0, _val, self); diff --git a/scripts/node_seperate_shape/node_seperate_shape.gml b/scripts/node_seperate_shape/node_seperate_shape.gml index 1a2b36caf..d83d1518e 100644 --- a/scripts/node_seperate_shape/node_seperate_shape.gml +++ b/scripts/node_seperate_shape/node_seperate_shape.gml @@ -1,6 +1,5 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Separate Shape"; - //error_update_enabled = true; inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) .rejectArray(); diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 705c1de0f..29d29d8ba 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -186,9 +186,11 @@ function value_color(i) { #region #8fde5d, //audiobit #4da6ff, //flipfluid ]; + static JUNCTION_COLORS_LENGTH = array_length(JUNCTION_COLORS); if(i == 99) return #8fde5d; - return JUNCTION_COLORS[safe_mod(max(0, i), array_length(JUNCTION_COLORS))]; + + return JUNCTION_COLORS[i]; } #endregion function value_color_bg(i) { #region @@ -1581,6 +1583,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static resetCache = function() { cache_value[0] = false; } + static getStaticValue = function() { INLINE return ds_list_empty(animator.values)? 0 : animator.values[| 0].value; } + static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region if(type == VALUE_TYPE.trigger) useCache = false; @@ -1595,7 +1599,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru cache_hit &= unit.reference == noone || unit.mode == VALUE_UNIT.constant; if(cache_hit) { - print($"Get cache {name} = {cache_value[2]}"); + //print($"Get cache {name} = {cache_value[2]}"); global.cache_hit++; return cache_value[2]; @@ -1627,9 +1631,25 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } #endregion static __getAnimValue = function(_time = CURRENT_FRAME) { #region + if(value_tag == "dimension" && node.attributes.use_project_dimension) return PROJECT.attributes.surface_dimension; + if(!is_anim) { + if(sep_axis) { + if(ds_list_empty(animators[i].values)) return 0; + + var val = array_verify(val, array_length(animators)); + for( var i = 0, n = array_length(animators); i < n; i++ ) + val[i] = animators[i].values[| 0].value; + return val; + } + + if(ds_list_empty(animator.values)) return 0; + + return animator.values[| 0].value; + } + if(sep_axis) { var val = []; for( var i = 0, n = array_length(animators); i < n; i++ ) @@ -1637,8 +1657,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return val; } - var _val = animator.getValue(_time); - return _val; + return animator.getValue(_time); } #endregion static arrayBalance = function(val) { #region //Balance array (generate uniform array from single values) @@ -1680,6 +1699,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } else val = valueExpressionProcess(val); return arrayBalance(val); + } #endregion if(typ == VALUE_TYPE.surface && (type == VALUE_TYPE.integer || type == VALUE_TYPE.float) && accept_array) { #region Dimension conversion @@ -1705,6 +1725,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } else if (is_surface(val)) return [ surface_get_width_safe(val), surface_get_height_safe(val) ]; return [1, 1]; + } #endregion val = arrayBalance(val); @@ -1714,31 +1735,31 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru for( var i = 0, n = array_length(val); i < n; i++ ) _val[i] = valueProcess(val[i], nod, applyUnit, arrIndex); return _val; + } #endregion return valueProcess(val, nod, applyUnit, arrIndex); } #endregion static getValueRecursive = function(_time = CURRENT_FRAME) { #region - var val = [ __getAnimValue(_time), self ]; if(type == VALUE_TYPE.trigger && connect_type == JUNCTION_CONNECT.output) //trigger event will not propagate from input to output, need to be done manually - return val; + return [ ds_list_empty(animator.values)? 0 : animator.values[| 0].value, self ]; + + var val = [ __getAnimValue(_time), self ]; if(value_from_loop && value_from_loop.bypassConnection() && value_from_loop.junc_out) val = value_from_loop.getValue(_time); + else if(value_from && value_from != self) val = value_from.getValueRecursive(_time); if(expUse && is_struct(expTree) && expTree.validate()) { - //print($"========== EXPRESSION CALLED =========="); - //print(debug_get_callstack(8)); if(global.EVALUATE_HEAD != noone && global.EVALUATE_HEAD == self) { noti_warning($"Expression evaluation error : recursive call detected."); + } else { - //print($"==================== EVAL BEGIN {expTree} ===================="); - //printCallStack(); global.EVALUATE_HEAD = self; expContext = { diff --git a/scripts/panel_animation/panel_animation.gml b/scripts/panel_animation/panel_animation.gml index 751a352ae..d82f537d8 100644 --- a/scripts/panel_animation/panel_animation.gml +++ b/scripts/panel_animation/panel_animation.gml @@ -26,6 +26,7 @@ function panel_animation_duplicate() { CALL("animation_duplicate"); PANEL_ANIMATION.doDuplicate(); } function panel_animation_copy() { CALL("animation_copy"); PANEL_ANIMATION.doCopy(); } function panel_animation_paste() { CALL("animation_paste"); PANEL_ANIMATION.doPaste(PANEL_ANIMATION.value_focusing); } + function panel_animation_show_nodes() { CALL("animation_paste"); PANEL_ANIMATION.show_nodes = !PANEL_ANIMATION.show_nodes; } #endregion enum KEYFRAME_DRAG_TYPE { @@ -70,8 +71,6 @@ function Panel_Animation() : PanelContent() constructor { dopesheet_dragging = noone; dopesheet_drag_mx = 0; - - dope_sheet_node_padding = ui(0); #endregion #region ---- timeline ---- @@ -122,6 +121,7 @@ function Panel_Animation() : PanelContent() constructor { #region ---- display ---- show_node_outside_context = true; + show_nodes = true; tooltip_loop_prop = noone; tooltip_loop_type = new tooltipSelector(__txtx("panel_animation_looping_mode", "Looping mode"), global.junctionEndName); @@ -138,7 +138,12 @@ function Panel_Animation() : PanelContent() constructor { hovering_folder = noone; hovering_order = noone; - node_name_type = 0; + node_name_type = 0; + node_name_tooltip = new tooltipSelector("Name Display", [ + __txtx("panel_animation_name_full", "Full name"), + __txtx("panel_animation_name_type", "Node type"), + __txtx("panel_animation_name_only", "Node name"), + ]); #endregion #region ---- stagger ---- @@ -202,6 +207,15 @@ function Panel_Animation() : PanelContent() constructor { #endregion #region ++++ hotkeys ++++ + + __collapse = false; + function collapseToggle() { #region + PANEL_ANIMATION.__collapse = !PANEL_ANIMATION.__collapse; + + for( var i = 0, n = array_length(PANEL_ANIMATION.timeline_contents); i < n; i++ ) + PANEL_ANIMATION.timeline_contents[i].item.show = PANEL_ANIMATION.__collapse; + } #endregion + addHotkey("", "Play/Pause", vk_space, MOD_KEY.none, panel_animation_play_pause); addHotkey("", "Resume/Pause", vk_space, MOD_KEY.shift, panel_animation_resume); @@ -214,6 +228,8 @@ function Panel_Animation() : PanelContent() constructor { addHotkey("Animation", "Duplicate", "D", MOD_KEY.ctrl, panel_animation_duplicate); addHotkey("Animation", "Copy", "C", MOD_KEY.ctrl, panel_animation_copy); addHotkey("Animation", "Paste", "V", MOD_KEY.ctrl, panel_animation_paste); + addHotkey("Animation", "Collapse Toggle", "C", MOD_KEY.none, collapseToggle); + addHotkey("Animation", "Toggle nodes", "H", MOD_KEY.none, panel_animation_show_nodes); #endregion #region ++++ context menu ++++ @@ -316,6 +332,15 @@ function Panel_Animation() : PanelContent() constructor { var _dir = new timelineItemGroup(); PROJECT.timelines.addItem(_dir); }, THEME.folder_content), + -1, + menuItem(__txt("Expand all"), function() { + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) + timeline_contents[i].item.show = true; + }), + menuItem(__txt("Collapse all"), function() { + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) + timeline_contents[i].item.show = false; + }), ]; var _clrs = COLORS.labels; @@ -345,7 +370,9 @@ function Panel_Animation() : PanelContent() constructor { name_menu_item = [ clr, -1, - name_menu_empty[0] + name_menu_empty[0], + name_menu_empty[2], + name_menu_empty[3], ]; name_menu_group = [ @@ -1082,7 +1109,7 @@ function Panel_Animation() : PanelContent() constructor { function _drawDopesheetAnimatorKeys(_cont, animator, msx, msy) { #region var _node = _cont.node; var prop_y = animator.y; - var node_y = _cont.y + dope_sheet_node_padding; + var node_y = _cont.y; var anim_set = true; var key_hover = noone; @@ -1265,9 +1292,19 @@ function Panel_Animation() : PanelContent() constructor { var cc = prop.sep_axis? COLORS.axis[animator.index] : COLORS._main_text_inner; if(hov) cc = COLORS._main_text_accent; + var _tx = ui(32); draw_set_color(cc); + + if(!show_nodes) { + var _txt = animator.prop.node.getDisplayName(); + + draw_set_alpha(aa * 0.5); + draw_text_add(_tx, ty - 2, _txt); + _tx += string_width(_txt) + ui(4); + } + draw_set_alpha(aa); - draw_text_add(ui(32), ty - 2, animator.getName()); + draw_text_add(_tx, ty - 2, animator.getName()); draw_set_alpha(1); } #endregion @@ -1322,7 +1359,7 @@ function Panel_Animation() : PanelContent() constructor { if(!_cont.show) continue; var _y = _cont.y; - var _h = _cont.h + dope_sheet_node_padding; + var _h = _cont.h; if(_y + _h < 0) continue; if(_y > h) break; @@ -1361,7 +1398,7 @@ function Panel_Animation() : PanelContent() constructor { if(!_cont.show) continue; var _y = _cont.y; - var _h = _cont.h + dope_sheet_node_padding; + var _h = _cont.h; if(_y + _h < 0) continue; if(_y > h) break; @@ -1373,7 +1410,7 @@ function Panel_Animation() : PanelContent() constructor { continue; } - __drawDopesheetLabelItem(_cont, 0, _cont.y + dope_sheet_node_padding, msx, msy); + if(show_nodes) __drawDopesheetLabelItem(_cont, 0, _cont.y, msx, msy); if(_cont.type == "node" && _cont.item.show) for( var j = 0; j < array_length(_cont.animators); j++ ) @@ -1433,9 +1470,9 @@ function Panel_Animation() : PanelContent() constructor { if(mouse_wheel_up()) dope_sheet_y_to = clamp(dope_sheet_y_to + ui(32) * SCROLL_SPEED, -dope_sheet_y_max, 0); } - var scr_x = bar_x + dope_sheet_w + ui(4); - var scr_y = ui(8); - var scr_s = dope_sheet_h; + var scr_x = bar_x + dope_sheet_w + ui(4); + var scr_y = ui(8); + var scr_s = dope_sheet_h; var scr_prog = -dope_sheet_y / dope_sheet_y_max; var scr_size = dope_sheet_h / (dope_sheet_h + dope_sheet_y_max); @@ -1490,8 +1527,6 @@ function Panel_Animation() : PanelContent() constructor { continue; var _expand = _cont.type == "node" && _cont.item.show; - key_y += dope_sheet_node_padding; - _cont.h += dope_sheet_node_padding; var _ks = key_y; if(_cont.item.color_dsp > -1) { @@ -1504,8 +1539,8 @@ function Panel_Animation() : PanelContent() constructor { var c1 = colorMultiply(_cont.item.color_cur, COLORS.panel_animation_dope_key_bg_hover); } - key_y += ui(20) + _expand * ui(10); - _cont.h += ui(20); + key_y += ui(20) * show_nodes + _expand * ui(10); + _cont.h += ui(20) * show_nodes; _ks = key_y - ui(10); if(_expand) { @@ -2083,16 +2118,16 @@ function Panel_Animation() : PanelContent() constructor { } by += ui(32); - var txt = ""; - switch(node_name_type) { - case 0 : txt = __txtx("panel_animation_name_full", "Show full name"); break; - case 1 : txt = __txtx("panel_animation_name_type", "Show node type"); break; - case 2 : txt = __txtx("panel_animation_name_only", "Show node name"); break; - } + node_name_tooltip.index = node_name_type; - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [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, node_name_tooltip, THEME.node_name_type, node_name_type) == 2) node_name_type = (node_name_type + 1) % 3; + by += ui(32); + txt = __txtx("panel_animation_show_node", "Toggle node label"); + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.junc_visible, show_nodes) == 2) + show_nodes = !show_nodes; + by += ui(32); txt = __txtx("panel_animation_keyframe_override", "Override Keyframe"); if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.keyframe_override, global.FLAG.keyframe_override) == 2)