diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 206e8c886..26d5dc4c8 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -1520,6 +1520,7 @@ {"name":"sh_draw_r16","order":10,"path":"shaders/sh_draw_r16/sh_draw_r16.yy",}, {"name":"sh_channel_S","order":5,"path":"shaders/sh_channel_S/sh_channel_S.yy",}, {"name":"string_scale","order":4,"path":"scripts/string_scale/string_scale.yy",}, + {"name":"node_struct_set","order":3,"path":"scripts/node_struct_set/node_struct_set.yy",}, {"name":"s_node_cache","order":27,"path":"sprites/s_node_cache/s_node_cache.yy",}, {"name":"node_repeat","order":9,"path":"scripts/node_repeat/node_repeat.yy",}, {"name":"draw_arc","order":22,"path":"scripts/draw_arc/draw_arc.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 20861181f..3c0e14d83 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -2257,6 +2257,7 @@ {"id":{"name":"sh_draw_r16","path":"shaders/sh_draw_r16/sh_draw_r16.yy",},}, {"id":{"name":"sh_channel_S","path":"shaders/sh_channel_S/sh_channel_S.yy",},}, {"id":{"name":"string_scale","path":"scripts/string_scale/string_scale.yy",},}, + {"id":{"name":"node_struct_set","path":"scripts/node_struct_set/node_struct_set.yy",},}, {"id":{"name":"s_node_cache","path":"sprites/s_node_cache/s_node_cache.yy",},}, {"id":{"name":"node_logic_operate","path":"scripts/node_logic_operate/node_logic_operate.yy",},}, {"id":{"name":"node_repeat","path":"scripts/node_repeat/node_repeat.yy",},}, diff --git a/scripts/_node_fluid_nodes/_node_fluid_nodes.gml b/scripts/_node_fluid_nodes/_node_fluid_nodes.gml index 9a81447b0..f75e0b5fe 100644 --- a/scripts/_node_fluid_nodes/_node_fluid_nodes.gml +++ b/scripts/_node_fluid_nodes/_node_fluid_nodes.gml @@ -16,16 +16,4 @@ function Node_Fluid(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { _to.node.updateForward(frame); } } - - static cachedPropagate = function() { - setRenderStatus(true); - - for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { - var _input = inputs[| i]; - if(_input.isLeaf()) continue; - if(!is_instanceof(_input.value_from.node, Node_Fluid)) continue; - - _input.value_from.node.cachedPropagate(); - } - } } \ No newline at end of file diff --git a/scripts/array_functions/array_functions.gml b/scripts/array_functions/array_functions.gml index d247fff9d..5d332c595 100644 --- a/scripts/array_functions/array_functions.gml +++ b/scripts/array_functions/array_functions.gml @@ -219,19 +219,38 @@ function array_shape(arr, first = true, isSurface = false) { return (first? "" : " x ") + dim; } -function array_spread(arr, _arr = []) { - if(!is_array(arr)) { +function array_depth(arr) { + gml_pragma("forceinline"); + + if(!is_array(arr)) return 0; + var d = 0; + var p = arr; + + while(is_array(p) && !array_empty(p)) { + d++; + p = p[0]; + } + + return d; +} + +function array_spread(arr, _arr = [], _minDepth = 0) { + gml_pragma("forceinline"); + + if(array_depth(arr) == _minDepth) { array_push(_arr, arr); return _arr; } for( var i = 0, n = array_length(arr); i < n; i++ ) - array_spread(arr[i], _arr); + array_spread(arr[i], _arr, _minDepth); return _arr; } function array_verify(arr, length) { + gml_pragma("forceinline"); + if(!is_array(arr)) return array_create(length); if(array_length(arr) == length) return arr; diff --git a/scripts/node_VFX_group/node_VFX_group.gml b/scripts/node_VFX_group/node_VFX_group.gml index f13416d7e..f9bb5dec2 100644 --- a/scripts/node_VFX_group/node_VFX_group.gml +++ b/scripts/node_VFX_group/node_VFX_group.gml @@ -73,9 +73,6 @@ function Node_VFX_Group(_x, _y, _group = noone) : Node_Collection(_x, _y, _group allCached = true; for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) { var node = nodes[| i]; - if(!is_instanceof(node, Node_VFX_Renderer_Output) && - !is_instanceof(node, Node_VFX_Renderer)) continue; - if(!node.recoverCache()) allCached = false; } diff --git a/scripts/node_VFX_variable/node_VFX_variable.gml b/scripts/node_VFX_variable/node_VFX_variable.gml index 3f5c1ac88..47e7dbf65 100644 --- a/scripts/node_VFX_variable/node_VFX_variable.gml +++ b/scripts/node_VFX_variable/node_VFX_variable.gml @@ -44,6 +44,9 @@ function Node_VFX_Variable(_x, _y, _group = noone) : Node(_x, _y, _group) constr .setDisplay(VALUE_DISPLAY.vector) .setVisible(false); + outputs[| 9] = nodeValue("Seed", self, JUNCTION_CONNECT.output, VALUE_TYPE.float, 0 ) + .setVisible(false); + static update = function(frame = CURRENT_FRAME) { var parts = getInputData(0); if(!is_array(parts)) return; @@ -64,7 +67,8 @@ function Node_VFX_Variable(_x, _y, _group = noone) : Node(_x, _y, _group) constr if(outputs[| 5].visible) _val[5][i] = part.life; if(outputs[| 6].visible) _val[6][i] = part.life_total; if(outputs[| 7].visible) _val[7][i] = part.surf; - if(outputs[| 8].visible) _val[8][i] = [part.sx, part.sy]; + if(outputs[| 8].visible) _val[8][i] = [part.speedx, part.speedy]; + if(outputs[| 9].visible) _val[9][i] = part.seed; } for( var i = 0; i < ds_list_size(outputs); i++ ) diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index ea92ddd11..3c3c34023 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -1387,6 +1387,18 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x arr[i]._clearCacheForward(); } #endregion + static cachedPropagate = function(_group = group) { #region + if(group != _group) return; + setRenderStatus(true); + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _input = inputs[| i]; + if(_input.isLeaf()) continue; + + _input.value_from.node.cachedPropagate(_group); + } + } #endregion + static clearInputCache = function() { #region for( var i = 0; i < ds_list_size(inputs); i++ ) { if(!is_instanceof(inputs[| i], NodeValue)) continue; diff --git a/scripts/node_fluid_sim/node_fluid_sim.gml b/scripts/node_fluid_sim/node_fluid_sim.gml index bc57c53c4..a5b790acb 100644 --- a/scripts/node_fluid_sim/node_fluid_sim.gml +++ b/scripts/node_fluid_sim/node_fluid_sim.gml @@ -63,8 +63,6 @@ function Node_Fluid_Group(_x, _y, _group = noone) : Node_Collection(_x, _y, _gro static update = function() { for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) { var node = nodes[| i]; - - if(!is_instanceof(node, Node_Fluid_Render)) continue; if(node.cacheExist()) node.cachedPropagate(); } diff --git a/scripts/node_path_builder/node_path_builder.gml b/scripts/node_path_builder/node_path_builder.gml index fbb4f4a9e..333cb005c 100644 --- a/scripts/node_path_builder/node_path_builder.gml +++ b/scripts/node_path_builder/node_path_builder.gml @@ -6,6 +6,9 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr length = 0; lengthAcc = []; + lines = []; + connected = false; + inputs[| 0] = nodeValue("Point array", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, []) .setVisible(true, true) .setArrayDepth(2); @@ -15,25 +18,22 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr outputs[| 0] = nodeValue("Path", self, JUNCTION_CONNECT.output, VALUE_TYPE.pathnode, self); static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region - var _lines = getInputData(0); - var _conn = getInputData(1); - draw_set_color(COLORS._main_accent); - if(_conn) { - for( var i = 1, n = array_length(_lines); i < n; i++ ) { - var p0 = _lines[i - 1]; - var p1 = _lines[i - 0]; + if(connected) { + for( var i = 1, n = array_length(lines); i < n; i++ ) { + var p0 = lines[i - 1]; + var p1 = lines[i - 0]; draw_line(_x + p0[0] * _s, _y + p0[1] * _s, _x + p1[0] * _s, _y + p1[1] * _s); } } else { - var len = floor(array_length(_lines) / 2) * 2; + var len = floor(array_length(lines) / 2) * 2; for( var i = 0; i < len; i += 2 ) { - var p0 = _lines[i + 0]; - var p1 = _lines[i + 1]; + var p0 = lines[i + 0]; + var p1 = lines[i + 1]; draw_line(_x + p0[0] * _s, _y + p0[1] * _s, _x + p1[0] * _s, _y + p1[1] * _s); @@ -42,17 +42,11 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr } #endregion static getLineCount = function() { #region - var _lines = getInputData(0); - var _conn = getInputData(1); - - return _conn? 1 : floor(array_length(_lines) / 2); + return connected? 1 : floor(array_length(lines) / 2); } #endregion static getSegmentCount = function() { #region - var _lines = getInputData(0); - var _conn = getInputData(1); - - return _conn? array_length(_lines) - 1 : 1; + return connected? array_length(lines) - 1 : 1; } #endregion static getLength = function(index) { return is_array(length)? array_safe_get(length, index) : length; } @@ -60,15 +54,13 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr static getAccuLength = function(index) { return array_safe_get(lengthAcc, index, []); } static getPointRatio = function(_rat, _ind = 0) { #region - var _lines = getInputData(0); - var _conn = getInputData(1); var _p0, _p1; var _x, _y; - if(_conn) { - var _st = _rat * (array_length(_lines) - 1); - _p0 = array_safe_get(_lines, floor(_st) + 0,, ARRAY_OVERFLOW._default); - _p1 = array_safe_get(_lines, floor(_st) + 1,, ARRAY_OVERFLOW._default); + if(connected) { + var _st = _rat * (array_length(lines) - 1); + _p0 = array_safe_get(lines, floor(_st) + 0,, ARRAY_OVERFLOW._default); + _p1 = array_safe_get(lines, floor(_st) + 1,, ARRAY_OVERFLOW._default); if(!is_array(_p0)) return new __vec2(); if(!is_array(_p1)) return new __vec2(); @@ -78,8 +70,8 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr return new __vec2( _x, _y ); } else { - _p0 = array_safe_get(_lines, _ind * 2 + 0,, ARRAY_OVERFLOW._default); - _p1 = array_safe_get(_lines, _ind * 2 + 1,, ARRAY_OVERFLOW._default); + _p0 = array_safe_get(lines, _ind * 2 + 0,, ARRAY_OVERFLOW._default); + _p1 = array_safe_get(lines, _ind * 2 + 1,, ARRAY_OVERFLOW._default); if(!is_array(_p0)) return new __vec2(); if(!is_array(_p1)) return new __vec2(); @@ -92,32 +84,31 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr } #endregion static getPointDistance = function(_dist, ind = 0) { #region - var _conn = getInputData(1); - - if(_conn) return getPointRatio(_dist / length); - else return getPointRatio(_dist / length[ind], ind); + if(connected) return getPointRatio(_dist / length); + else return getPointRatio(_dist / length[ind], ind); } #endregion static getBoundary = function() { #region var boundary = new BoundingBox(); - var _lines = getInputData(0); - for( var i = 0, n = array_length(_lines); i < n; i++ ) - boundary.addPoint(_lines[i][0], _lines[i][1]); + var lines = getInputData(0); + for( var i = 0, n = array_length(lines); i < n; i++ ) + boundary.addPoint(lines[i][0], lines[i][1]); return boundary; } #endregion static update = function() { #region - var _lines = getInputData(0); - var _conn = getInputData(1); + lines = []; + array_spread(getInputData(0), lines, 1); + connected = getInputData(1); - if(_conn) { + if(connected) { length = 0; lengthAcc = []; - for( var i = 1, n = array_length(_lines); i < n; i++ ) { - var p0 = _lines[i - 1]; - var p1 = _lines[i - 0]; + for( var i = 1, n = array_length(lines); i < n; i++ ) { + var p0 = lines[i - 1]; + var p1 = lines[i - 0]; var dist = point_distance(p0[0], p0[1], p1[0], p1[1]); @@ -125,16 +116,29 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr array_push(lengthAcc, length); } } else { - length = []; + length = []; lengthAcc = []; - var len = floor(array_length(_lines) / 2) * 2; + var len = floor(array_length(lines) / 2) * 2; for( var i = 0; i < len; i += 2 ) { - var p0 = _lines[i + 0]; - var p1 = _lines[i + 1]; + var p0 = lines[i + 0]; + var p1 = lines[i + 1]; - var dist = point_distance(p0[0], p0[1], p1[0], p1[1]); + var p0x = array_safe_get(p0, 0); + var p0y = array_safe_get(p0, 1); + var p1x = array_safe_get(p1, 0); + var p1y = array_safe_get(p1, 1); + + p0x = is_real(p0x)? p0x : 0; + p0y = is_real(p0y)? p0y : 0; + p1x = is_real(p1x)? p1x : 0; + p1y = is_real(p1y)? p1y : 0; + + lines[i + 0] = [ p0x, p0y ]; + lines[i + 1] = [ p1x, p1y ]; + + var dist = point_distance(p0x, p0y, p1x, p1y); array_push(length, dist); array_push(lengthAcc, [ dist ]); diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 2ad7220e8..5292c775c 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -606,6 +606,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { #regio ds_list_add(values, "Struct"); addNodeObject(values, "Struct", s_node_struct, "Node_Struct", [1, Node_Struct]); addNodeObject(values, "Struct Get", s_node_struct_get, "Node_Struct_Get", [1, Node_Struct_Get]); + //addNodeObject(values, "Struct Set", s_node_struct_get, "Node_Struct_Set", [1, Node_Struct_Set]); addNodeObject(values, "Parse JSON", s_node_json_parse, "Node_Struct_JSON_Parse", [1, Node_Struct_JSON_Parse]).setVersion(1145); ds_list_add(values, "Mesh"); diff --git a/scripts/node_struct_get/node_struct_get.gml b/scripts/node_struct_get/node_struct_get.gml index 3856acfbe..c530f2d55 100644 --- a/scripts/node_struct_get/node_struct_get.gml +++ b/scripts/node_struct_get/node_struct_get.gml @@ -11,54 +11,72 @@ function Node_Struct_Get(_x, _y, _group = noone) : Node(_x, _y, _group) construc outputs[| 0] = nodeValue("Struct", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, {}); - static update = function() { + static getStructValue = function(str, keys) { #region + var _pnt = str, val = 0; + if(!is_struct(_pnt)) return [ VALUE_TYPE.any, val ]; + + for( var j = 0; j < array_length(keys); j++ ) { + var k = keys[j]; + + if(!variable_struct_exists(_pnt, k)) + return [ VALUE_TYPE.float, 0 ]; + + val = variable_struct_get(_pnt, k); + if(j == array_length(keys) - 1) { + if(is_struct(val)) { + if(is_instanceof(val, Surface)) + return [ VALUE_TYPE.surface, val.get() ]; + else if(is_instanceof(val, Buffer)) + return [ VALUE_TYPE.buffer, val.buffer ]; + else + return [ VALUE_TYPE.struct, val ]; + } else if(is_array(val) && array_length(val)) + return [ is_string(val[0])? VALUE_TYPE.text : VALUE_TYPE.float, val ]; + else + return [ is_string(val)? VALUE_TYPE.text : VALUE_TYPE.float, val ]; + } + + if(is_struct(val)) _pnt = val; + else break; + } + + return [ VALUE_TYPE.any, val ]; + } #endregion + + static update = function() { #region var str = getInputData(0); var key = getInputData(1); var keys = string_splice(key, "."); - var _str = str; - var out = outputs[| 0]; + if(is_array(str)) { + var typ = VALUE_TYPE.any; + var val = array_create(array_length(str)); + + for( var i = 0, n = array_length(str); i < n; i++ ) { + var _str = str[i]; + var _v = getStructValue(_str, keys); + + typ = _v[0]; + val[i] = _v[1]; + } + + outputs[| 0].setType(typ); + outputs[| 0].setValue(val); + } else { + var val = getStructValue(str, keys); - for( var j = 0; j < array_length(keys); j++ ) { - var k = keys[j]; - - if(!variable_struct_exists(_str, k)) { - out.setValue(0); - out.setType(VALUE_TYPE.float); - break; - } - - var val = variable_struct_get(_str, k); - if(j == array_length(keys) - 1) { - if(is_struct(val)) { - if(is_instanceof(val, Surface)) { - out.setType(VALUE_TYPE.surface); - val = val.get(); - } else if(is_instanceof(val, Buffer)) { - out.setType(VALUE_TYPE.buffer); - val = val.buffer; - } else - out.setType(VALUE_TYPE.struct); - } else if(is_array(val) && array_length(val)) - out.setType(is_string(val[0])? VALUE_TYPE.text : VALUE_TYPE.float); - else - out.setType(is_string(val)? VALUE_TYPE.text : VALUE_TYPE.float); - - out.setValue(val); - } - - if(is_struct(val)) _str = val; - else break; + outputs[| 0].setType(val[0]); + outputs[| 0].setValue(val[1]); } - } + } #endregion - static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region var bbox = drawGetBbox(xx, yy, _s); var str = getInputData(1); draw_set_text(f_h5, fa_center, fa_center, COLORS._main_text); var ss = string_scale(str, bbox.w, bbox.h); draw_text_transformed(bbox.xc, bbox.yc, str, ss, ss, 0); - } + } #endregion } \ No newline at end of file diff --git a/scripts/node_struct_set/node_struct_set.gml b/scripts/node_struct_set/node_struct_set.gml new file mode 100644 index 000000000..6237b9d92 --- /dev/null +++ b/scripts/node_struct_set/node_struct_set.gml @@ -0,0 +1,66 @@ +function Node_Struct_Set(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Struct Set"; + previewable = false; + + w = 96; + + inputs[| 0] = nodeValue("Struct", self, JUNCTION_CONNECT.input, VALUE_TYPE.struct, {}) + .setVisible(true, true); + + inputs[| 1] = nodeValue("Key", self, JUNCTION_CONNECT.input, VALUE_TYPE.text, ""); + + inputs[| 2] = nodeValue("Value", self, JUNCTION_CONNECT.input, VALUE_TYPE.any, 0); + + outputs[| 0] = nodeValue("Struct", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, {}); + + static update = function() { + var str = getInputData(0); + var key = getInputData(1); + var val = getInputData(2); + + var keys = string_splice(key, "."); + var _str = str; + + var out = outputs[| 0]; + + for( var j = 0; j < array_length(keys); j++ ) { + var k = keys[j]; + + if(!variable_struct_exists(_str, k)) { + out.setType(VALUE_TYPE.float); + break; + } + + var val = variable_struct_get(_str, k); + if(j == array_length(keys) - 1) { + if(is_struct(val)) { + if(is_instanceof(val, Surface)) { + out.setType(VALUE_TYPE.surface); + val = val.get(); + } else if(is_instanceof(val, Buffer)) { + out.setType(VALUE_TYPE.buffer); + val = val.buffer; + } else + out.setType(VALUE_TYPE.struct); + } else if(is_array(val) && array_length(val)) + out.setType(is_string(val[0])? VALUE_TYPE.text : VALUE_TYPE.float); + else + out.setType(is_string(val)? VALUE_TYPE.text : VALUE_TYPE.float); + + out.setValue(val); + } + + if(is_struct(val)) _str = val; + else break; + } + } + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + var str = getInputData(1); + + draw_set_text(f_h5, fa_center, fa_center, COLORS._main_text); + var ss = string_scale(str, bbox.w, bbox.h); + draw_text_transformed(bbox.xc, bbox.yc, str, ss, ss, 0); + } +} \ No newline at end of file diff --git a/scripts/node_struct_set/node_struct_set.yy b/scripts/node_struct_set/node_struct_set.yy new file mode 100644 index 000000000..373776c75 --- /dev/null +++ b/scripts/node_struct_set/node_struct_set.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_struct_set", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "struct", + "path": "folders/nodes/data/value/struct.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 6c21f3f11..4b90490f3 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -288,8 +288,9 @@ function value_type_directional(f, t) { #region if(f == VALUE_TYPE.strands && t == VALUE_TYPE.pathnode ) return true; - if(f == VALUE_TYPE.color && t == VALUE_TYPE.struct ) return true; - if(f == VALUE_TYPE.mesh && t == VALUE_TYPE.struct ) return true; + if(f == VALUE_TYPE.color && t == VALUE_TYPE.struct ) return true; + if(f == VALUE_TYPE.mesh && t == VALUE_TYPE.struct ) return true; + if(f == VALUE_TYPE.particle && t == VALUE_TYPE.struct ) return true; if(f == VALUE_TYPE.surface && t == VALUE_TYPE.d3Material ) return true;