diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index e2dcaf0b2..82c5f70f1 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -51,6 +51,7 @@ {"name":"drawer","order":11,"path":"folders/nodes/data/generator/drawer.yy",}, {"name":"noise","order":14,"path":"folders/nodes/data/generator/noise.yy",}, {"name":"pattern","order":15,"path":"folders/nodes/data/generator/pattern.yy",}, + {"name":"ray march","order":21,"path":"folders/nodes/data/generator/ray march.yy",}, {"name":"regions","order":19,"path":"folders/nodes/data/generator/regions.yy",}, {"name":"group","order":18,"path":"folders/nodes/data/group.yy",}, {"name":"io","order":19,"path":"folders/nodes/data/io.yy",}, @@ -157,6 +158,7 @@ {"name":"find_boundary","order":7,"path":"folders/shader/misc/find_boundary.yy",}, {"name":"Flag","order":3,"path":"folders/shader/MK effects/Flag.yy",}, {"name":"Tile","order":4,"path":"folders/shader/MK effects/Tile.yy",}, + {"name":"ray march","order":1,"path":"folders/shader/ray march.yy",}, {"name":"histogram","order":4,"path":"folders/shader/UI/histogram.yy",}, {"name":"palette mixer","order":2,"path":"folders/shader/UI/palette mixer.yy",}, ], @@ -955,6 +957,7 @@ {"name":"node_rigid_variable","order":11,"path":"scripts/node_rigid_variable/node_rigid_variable.yy",}, {"name":"node_rigid_wall","order":12,"path":"scripts/node_rigid_wall/node_rigid_wall.yy",}, {"name":"node_rim","order":22,"path":"scripts/node_rim/node_rim.yy",}, + {"name":"node_rm_primitive","order":1,"path":"scripts/node_rm_primitive/node_rm_primitive.yy",}, {"name":"node_sampler","order":3,"path":"scripts/node_sampler/node_sampler.yy",}, {"name":"node_scale_algo","order":12,"path":"scripts/node_scale_algo/node_scale_algo.yy",}, {"name":"node_scale","order":8,"path":"scripts/node_scale/node_scale.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 68ac0fec2..42c3d152f 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -149,6 +149,7 @@ {"$GMFolder":"","%Name":"drawer","folderPath":"folders/nodes/data/generator/drawer.yy","name":"drawer","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"noise","folderPath":"folders/nodes/data/generator/noise.yy","name":"noise","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"pattern","folderPath":"folders/nodes/data/generator/pattern.yy","name":"pattern","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"ray march","folderPath":"folders/nodes/data/generator/ray march.yy","name":"ray march","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"regions","folderPath":"folders/nodes/data/generator/regions.yy","name":"regions","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"group","folderPath":"folders/nodes/data/group.yy","name":"group","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"io","folderPath":"folders/nodes/data/io.yy","name":"io","resourceType":"GMFolder","resourceVersion":"2.0",}, @@ -292,6 +293,7 @@ {"$GMFolder":"","%Name":"Flag","folderPath":"folders/shader/MK effects/Flag.yy","name":"Flag","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"Tile","folderPath":"folders/shader/MK effects/Tile.yy","name":"Tile","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"pixel_builder","folderPath":"folders/shader/pixel_builder.yy","name":"pixel_builder","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"ray march","folderPath":"folders/shader/ray march.yy","name":"ray march","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"sprites","folderPath":"folders/shader/sprites.yy","name":"sprites","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"transition","folderPath":"folders/shader/transition.yy","name":"transition","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"UI","folderPath":"folders/shader/UI.yy","name":"UI","resourceType":"GMFolder","resourceVersion":"2.0",}, @@ -1399,6 +1401,7 @@ {"id":{"name":"node_rigid_variable","path":"scripts/node_rigid_variable/node_rigid_variable.yy",},}, {"id":{"name":"node_rigid_wall","path":"scripts/node_rigid_wall/node_rigid_wall.yy",},}, {"id":{"name":"node_rim","path":"scripts/node_rim/node_rim.yy",},}, + {"id":{"name":"node_rm_primitive","path":"scripts/node_rm_primitive/node_rm_primitive.yy",},}, {"id":{"name":"node_sampler","path":"scripts/node_sampler/node_sampler.yy",},}, {"id":{"name":"node_scale_algo","path":"scripts/node_scale_algo/node_scale_algo.yy",},}, {"id":{"name":"node_scale","path":"scripts/node_scale/node_scale.yy",},}, @@ -1997,6 +2000,7 @@ {"id":{"name":"sh_remove_black","path":"shaders/sh_remove_black/sh_remove_black.yy",},}, {"id":{"name":"sh_replace_color","path":"shaders/sh_replace_color/sh_replace_color.yy",},}, {"id":{"name":"sh_rim","path":"shaders/sh_rim/sh_rim.yy",},}, + {"id":{"name":"sh_rm_primitive","path":"shaders/sh_rm_primitive/sh_rm_primitive.yy",},}, {"id":{"name":"sh_rsh_corner","path":"shaders/sh_rsh_corner/sh_rsh_corner.yy",},}, {"id":{"name":"sh_rsh_erode","path":"shaders/sh_rsh_erode/sh_rsh_erode.yy",},}, {"id":{"name":"sh_rsh_rotate","path":"shaders/sh_rsh_rotate/sh_rsh_rotate.yy",},}, diff --git a/scripts/node_array/node_array.gml b/scripts/node_array/node_array.gml index 2d0fab8a4..c9500142e 100644 --- a/scripts/node_array/node_array.gml +++ b/scripts/node_array/node_array.gml @@ -67,7 +67,7 @@ function Node_Array(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { for( var i = 0; i < ds_list_size(inputs); i++ ) { var _inp = inputs[| i]; - if(i < input_fix_len + amo || _inp.value_from) + if(i < input_fix_len + amo || _inp.hasJunctionFrom()) ds_list_add(_l, _inp); } diff --git a/scripts/node_composite/node_composite.gml b/scripts/node_composite/node_composite.gml index 84d594dcb..6d5fd6e41 100644 --- a/scripts/node_composite/node_composite.gml +++ b/scripts/node_composite/node_composite.gml @@ -430,8 +430,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) var _vis = attributes.layer_visible; var _sel = attributes.layer_selectable; - var amo = getInputAmount(); - + var amo = getInputAmount(); var anchors = array_create(ds_list_size(inputs)); for(var i = 0; i < amo; i++) { @@ -493,6 +492,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) if(!_surf || is_array(_surf)) continue; var a = anchors[index]; + if(!is_struct(a)) continue; if(surface_selecting == index) { var _ri = 0; @@ -513,6 +513,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) draw_sprite_colored(THEME.anchor_rotate, _ri, a.rr[0], a.rr[1],, a.rot); draw_sprite_colored(THEME.anchor_scale, _si, a.d3[0], a.d3[1],, a.rot); + } else if(point_in_rectangle_points(_mx, _my, a.d0[0], a.d0[1], a.d1[0], a.d1[1], a.d2[0], a.d2[1], a.d3[0], a.d3[1]) && (hovering != surface_selecting || surface_selecting == noone)) { diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index d5e42e5a8..db27c90df 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -352,7 +352,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { /////========== DYNAMIC IO ========== - auto_input = false; + dummy_input = noone; + auto_input = false; dyna_input_check_shift = 0; static createNewInput = -1; @@ -388,11 +389,13 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { for( var i = input_fix_len; i < ds_list_size(inputs); i += data_length ) { var _active = false; + var _inp = inputs[| i + dyna_input_check_shift]; + if(dynamic_input_cond & DYNA_INPUT_COND.connection) - _active |= inputs[| i + dyna_input_check_shift].value_from != noone; + _active |= _inp.hasJunctionFrom(); if(dynamic_input_cond & DYNA_INPUT_COND.zero) { - var _val = inputs[| i + dyna_input_check_shift].getValue(); + var _val = _inp.getValue(); _active |= _val != 0 || _val != ""; } @@ -413,9 +416,12 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { } } - for( var i = 0; i < ds_list_size(_in); i++ ) + var _ina = ds_list_size(_in); + for( var i = 0; i < _ina; i++ ) _in[| i].index = i; + if(dummy_input) dummy_input.index = _ina; + ds_list_destroy(inputs); inputs = _in; diff --git a/scripts/node_feedback_inline/node_feedback_inline.gml b/scripts/node_feedback_inline/node_feedback_inline.gml index d64552fca..c2520a453 100644 --- a/scripts/node_feedback_inline/node_feedback_inline.gml +++ b/scripts/node_feedback_inline/node_feedback_inline.gml @@ -23,6 +23,14 @@ function Node_Feedback_Inline(_x, _y, _group = noone) : Node(_x, _y, _group) con static bypassNextNode = function() { return false; } static getNextNode = function() { return [] }; + static connectJunctions = function(jFrom, jTo) { + junc_in = jFrom.is_dummy? jFrom.dummy_get() : jFrom; + junc_out = jTo; + + attributes.junc_in = [ junc_in .node.node_id, junc_in .index ]; + attributes.junc_out = [ junc_out.node.node_id, junc_out.index ]; + } + static scanJunc = function() { #region var node_in = PROJECT.nodeMap[? attributes.junc_in[0]]; var node_out = PROJECT.nodeMap[? attributes.junc_out[0]]; diff --git a/scripts/node_iterate_inline/node_iterate_inline.gml b/scripts/node_iterate_inline/node_iterate_inline.gml index 507e9a53b..fcc414ea4 100644 --- a/scripts/node_iterate_inline/node_iterate_inline.gml +++ b/scripts/node_iterate_inline/node_iterate_inline.gml @@ -44,6 +44,14 @@ function Node_Iterate_Inline(_x, _y, _group = noone) : Node_Collection_Inline(_x return _nodes; } #endregion + static connectJunctions = function(jFrom, jTo) { + junc_in = jFrom.is_dummy? jFrom.dummy_get() : jFrom; + junc_out = jTo; + + attributes.junc_in = [ junc_in .node.node_id, junc_in .index ]; + attributes.junc_out = [ junc_out.node.node_id, junc_out.index ]; + } + static scanJunc = function() { #region var node_in = PROJECT.nodeMap[? attributes.junc_in[0]]; var node_out = PROJECT.nodeMap[? attributes.junc_out[0]]; diff --git a/scripts/node_path/node_path.gml b/scripts/node_path/node_path.gml index 973902d50..87167b96a 100644 --- a/scripts/node_path/node_path.gml +++ b/scripts/node_path/node_path.gml @@ -567,9 +567,9 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { var _seg = segments[i]; var _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; - for( var j = 0, m = array_length(_seg); j < m; j++ ) { - _nx = _x + _seg[j][0] * _s; - _ny = _y + _seg[j][1] * _s; + for( var j = 0, m = array_length(_seg); j < m; j += 2 ) { + _nx = _x + _seg[j + 0] * _s; + _ny = _y + _seg[j + 1] * _s; minx = min(minx, _nx); maxx = max(maxx, _nx); miny = min(miny, _ny); maxy = max(maxy, _ny); @@ -816,18 +816,20 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { var _a1 = anchors[(i + 1) % ansize]; var l = 0, _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; - var sg = array_create(sample); + var sg = array_create((sample + 1) * 2); for(var j = 0; j <= sample; j++) { - if(_a0[4] == 0 && _a0[5] == 0 && _a1[2] == 0 && _a1[3] == 0) - p = [ lerp(_a0[0], _a1[0], j / sample), lerp(_a0[1], _a1[1], j / sample) ]; - else - p = eval_bezier(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], - _a0[0] + _a0[4], _a0[1] + _a0[5], - _a1[0] + _a1[2], _a1[1] + _a1[3]); - sg[j] = p; - _nx = p[0]; - _ny = p[1]; + + if(_a0[4] == 0 && _a0[5] == 0 && _a1[2] == 0 && _a1[3] == 0) { + _nx = lerp(_a0[0], _a1[0], j / sample); + _ny = lerp(_a0[1], _a1[1], j / sample); + } else { + _nx = eval_bezier_x(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + _ny = eval_bezier_y(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + } + + sg[j * 2 + 0] = _nx; + sg[j * 2 + 1] = _ny; boundary.addPoint(_nx, _ny); if(j) l += point_distance(_nx, _ny, _ox, _oy); @@ -880,9 +882,14 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { } var _t = _dist / lengths[i]; - var _p = eval_bezier(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); - out.x = _p[0]; - out.y = _p[1]; + + if(_a0[4] == 0 && _a0[5] == 0 && _a1[2] == 0 && _a1[3] == 0) { + out.x = lerp(_a0[0], _a1[0], _t); + out.y = lerp(_a0[1], _a1[1], _t); + } else { + out.x = eval_bezier_x(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + out.y = eval_bezier_y(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + } cached_pos[? _cKey] = out.clone(); return out; @@ -913,9 +920,17 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { var _a0 = anchors[_i0]; var _a1 = anchors[_i1]; - var p = eval_bezier(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + var px, py; - return new __vec2(p[0], p[1]); + if(_a0[4] == 0 && _a0[5] == 0 && _a1[2] == 0 && _a1[3] == 0) { + px = lerp(_a0[0], _a1[0], _t); + py = lerp(_a0[1], _a1[1], _t); + } else { + px = eval_bezier_x(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + py = eval_bezier_y(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + } + + return new __vec2(px, py); } #endregion static update = function(frame = CURRENT_FRAME) { #region diff --git a/scripts/node_path_bridge/node_path_bridge.gml b/scripts/node_path_bridge/node_path_bridge.gml index 405522b8f..896ee5de2 100644 --- a/scripts/node_path_bridge/node_path_bridge.gml +++ b/scripts/node_path_bridge/node_path_bridge.gml @@ -133,9 +133,8 @@ function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _c1x = _cnt[_ind][2]; var _c1y = _cnt[_ind][3]; - var _p = eval_bezier(_rat, p0[0], p0[1], p1[0], p1[1], _c0x, _c0y, _c1x, _c1y); - out.x = _p[0]; - out.y = _p[1]; + out.x = eval_bezier_x(_rat, p0[0], p0[1], p1[0], p1[1], _c0x, _c0y, _c1x, _c1y); + out.y = eval_bezier_y(_rat, p0[0], p0[1], p1[0], p1[1], _c0x, _c0y, _c1x, _c1y); } else { out.x = lerp(p0[0], p1[0], _rat); @@ -221,10 +220,9 @@ function Node_Path_Bridge(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _ll = 0; for( var k = 0; k < 1; k += _smp ) { - var _p = eval_bezier(k, _a0[0], _a0[1], _a1[0], _a1[1], _c0x, _c0y, _c1x, _c1y); - nx = _p[0]; - ny = _p[1]; - + nx = eval_bezier_x(k, _a0[0], _a0[1], _a1[0], _a1[1], _c0x, _c0y, _c1x, _c1y); + ny = eval_bezier_y(k, _a0[0], _a0[1], _a1[0], _a1[1], _c0x, _c0y, _c1x, _c1y); + if(k > 0) _ll += point_distance(ox, oy, nx, ny); ox = nx; diff --git a/scripts/node_path_builder/node_path_builder.gml b/scripts/node_path_builder/node_path_builder.gml index 518642641..167f1a9de 100644 --- a/scripts/node_path_builder/node_path_builder.gml +++ b/scripts/node_path_builder/node_path_builder.gml @@ -36,9 +36,9 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _seg = segments[i]; var _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; - for( var j = 0, m = array_length(_seg); j < m; j++ ) { - _nx = _x + _seg[j][0] * _s; - _ny = _y + _seg[j][1] * _s; + for( var j = 0, m = array_length(_seg); j < m; j += 2 ) { + _nx = _x + _seg[j + 0] * _s; + _ny = _y + _seg[j + 1] * _s; if(j) draw_line_width(_ox, _oy, _nx, _ny, 1); @@ -81,15 +81,20 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _a1 = anchors[(i + 1) % ansize]; var l = 0, _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; - var sg = array_create(sample); + var sg = array_create((sample + 1) * 2); for(var j = 0; j <= sample; j++) { - p = eval_bezier(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], - _a0[0] + _a0[4], _a0[1] + _a0[5], - _a1[0] + _a1[2], _a1[1] + _a1[3]); - sg[j] = p; - _nx = p[0]; - _ny = p[1]; + + if(_a0[4] == 0 && _a0[5] == 0 && _a1[2] == 0 && _a1[3] == 0) { + _nx = lerp(_a0[0], _a1[0], j / sample); + _ny = lerp(_a0[1], _a1[1], j / sample); + } else { + _nx = eval_bezier_x(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + _ny = eval_bezier_y(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + } + + sg[j * 2 + 0] = _nx; + sg[j * 2 + 1] = _ny; boundary.addPoint(_nx, _ny); if(j) l += point_distance(_nx, _ny, _ox, _oy); @@ -142,9 +147,14 @@ function Node_Path_Builder(_x, _y, _group = noone) : Node(_x, _y, _group) constr } var _t = _dist / lengths[i]; - var _p = eval_bezier(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); - out.x = _p[0]; - out.y = _p[1]; + + if(_a0[4] == 0 && _a0[5] == 0 && _a1[2] == 0 && _a1[3] == 0) { + out.x = lerp(_a0[0], _a1[0], _t); + out.y = lerp(_a0[1], _a1[1], _t); + } else { + out.x = eval_bezier_x(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + out.y = eval_bezier_y(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _a0[4], _a0[1] + _a0[5], _a1[0] + _a1[2], _a1[1] + _a1[3]); + } cached_pos[? _cKey] = out.clone(); return out; diff --git a/scripts/node_path_smooth/node_path_smooth.gml b/scripts/node_path_smooth/node_path_smooth.gml index eda61b003..601ae89bb 100644 --- a/scripts/node_path_smooth/node_path_smooth.gml +++ b/scripts/node_path_smooth/node_path_smooth.gml @@ -82,9 +82,9 @@ function Node_Path_Smooth(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _seg = segments[i]; var _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; - for( var j = 0, m = array_length(_seg); j < m; j++ ) { - _nx = _x + _seg[j][0] * _s; - _ny = _y + _seg[j][1] * _s; + for( var j = 0, m = array_length(_seg); j < m; j += 2 ) { + _nx = _x + _seg[j + 0] * _s; + _ny = _y + _seg[j + 1] * _s; if(j) { if((key_mod_press(CTRL) || isUsingTool(0)) && distance_to_line(_mx, _my, _ox, _oy, _nx, _ny) < 4) @@ -156,15 +156,20 @@ function Node_Path_Smooth(_x, _y, _group = noone) : Node(_x, _y, _group) constru var _c1 = controls[(i + 1) % ansize]; var l = 0, _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; - var sg = array_create(sample); + var sg = array_create(sample * 2); for(var j = 0; j < sample; j++) { - p = eval_bezier(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], - _a0[0] + _c0[2], _a0[1] + _c0[3], - _a1[0] + _c1[0], _a1[1] + _c1[1]); - sg[j] = p; - _nx = p[0]; - _ny = p[1]; + + if(_c0[2] == 0 && _c0[3] == 0 && _c1[0] == 0 && _c1[1] == 0) { + _nx = lerp(_a0[0], _a1[0], j / sample); + _ny = lerp(_a0[1], _a1[1], j / sample); + } else { + _nx = eval_bezier_x(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _c0[2], _a0[1] + _c0[3], _a1[0] + _c1[0], _a1[1] + _c1[1]); + _ny = eval_bezier_y(j / sample, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _c0[2], _a0[1] + _c0[3], _a1[0] + _c1[0], _a1[1] + _c1[1]); + } + + sg[j * 2 + 0] = _nx; + sg[j * 2 + 1] = _ny; boundary.addPoint(_nx, _ny); if(j) l += point_distance(_nx, _ny, _ox, _oy); @@ -217,11 +222,14 @@ function Node_Path_Smooth(_x, _y, _group = noone) : Node(_x, _y, _group) constru } var _t = _dist / lengths[i]; - var _p = eval_bezier(_t, _a0[0], _a0[1], _a1[0], _a1[1], - _a0[0] + _c0[2], _a0[1] + _c0[3], - _a1[0] + _c1[0], _a1[1] + _c1[1]); - out.x = _p[0]; - out.y = _p[1]; + + if(_c0[2] == 0 && _c0[3] == 0 && _c1[0] == 0 && _c1[1] == 0) { + out.x = lerp(_a0[0], _a1[0], _t); + out.y = lerp(_a0[1], _a1[1], _t); + } else { + out.x = eval_bezier_x(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _c0[2], _a0[1] + _c0[3], _a1[0] + _c1[0], _a1[1] + _c1[1]); + out.y = eval_bezier_y(_t, _a0[0], _a0[1], _a1[0], _a1[1], _a0[0] + _c0[2], _a0[1] + _c0[3], _a1[0] + _c1[0], _a1[1] + _c1[1]); + } cached_pos[? _cKey] = out.clone(); return out; diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 887470ff7..f29f257d5 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -532,7 +532,7 @@ function __initNodes() { ds_list_add(transform, "Warps"); addNodeObject(transform, "Crop", s_node_crop, "Node_Crop", [1, Node_Crop],, "Crop out image to create smaller ones."); - addNodeObject(transform, "Crop Content", s_node_crop_content, "Node_Crop_Content", [1, Node_Crop_Content],, "Crop out empty pixel pixel from the image."); + addNodeObject(transform, "Crop Content", s_node_crop_content, "Node_Crop_Content", [1, Node_Crop_Content],, "Crop out empty pixel from the image."); addNodeObject(transform, "Bend", s_node_bend, "Node_Bend", [1, Node_Bend], ["wrap"]).setVersion(11650); addNodeObject(transform, "Warp", s_node_warp, "Node_Warp", [1, Node_Warp], ["warp corner"], "Warp image by freely moving the corners."); addNodeObject(transform, "Skew", s_node_skew, "Node_Skew", [1, Node_Skew], ["shear"], "Skew image horizontally, or vertically."); @@ -553,7 +553,7 @@ function __initNodes() { //addNodeObject(filter, "Lovify", s_node_lovify, "Node_Lovify", [1, Node_Lovify],, "Add love to your image.").setIcon(s_lovify_icon); ds_list_add(filter, "Combines"); - addNodeObject(filter, "Blend", s_node_blend, "Node_Blend", [0, Node_create_Blend], global.node_blend_keys, "Blend 2 images using different blendmodes."); + addNodeObject(filter, "Blend", s_node_blend, "Node_Blend", [0, Node_create_Blend], global.node_blend_keys, "Blend 2 images using different blend modes."); addNodeObject(filter, "RGBA Combine", s_node_RGB_combine, "Node_Combine_RGB", [1, Node_Combine_RGB],, "Combine 4 image in to one. Each image use to control RGBA channel.").setVersion(1070); addNodeObject(filter, "HSV Combine", s_node_HSV_combine, "Node_Combine_HSV", [1, Node_Combine_HSV],, "Combine 4 image in to one. Each image use to control HSVA channel.").setVersion(1070); addNodeObject(filter, "Override Channel", s_node_ovreride_channel, "Node_Override_Channel", [1, Node_Override_Channel],, "Replace RGBA value of one surface with anothers.").setVersion(11640); @@ -564,7 +564,7 @@ function __initNodes() { addNodeObject(filter, "Directional Blur", s_node_blur_directional,"Node_Blur_Directional",[1, Node_Blur_Directional], ["motion blur"], "Blur image given a direction."); addNodeObject(filter, "Slope Blur", s_node_blur_slope, "Node_Blur_Slope", [1, Node_Blur_Slope], ["motion blur"], "Blur along a gradient of a slope map.").setVersion(11640); addNodeObject(filter, "Zoom Blur", s_node_zoom, "Node_Blur_Zoom", [1, Node_Blur_Zoom],, "Blur image by zooming in/out from a mid point."); - addNodeObject(filter, "Radial Blur", s_node_radial, "Node_Blur_Radial", [1, Node_Blur_Radial],, "Blur image by rotating aroung a mid point.").setVersion(1110); + addNodeObject(filter, "Radial Blur", s_node_radial, "Node_Blur_Radial", [1, Node_Blur_Radial],, "Blur image by rotating around a mid point.").setVersion(1110); addNodeObject(filter, "Lens Blur", s_node_bokeh, "Node_Blur_Bokeh", [1, Node_Blur_Bokeh], ["bokeh"], "Create bokeh effect. Blur lighter color in a lens-like manner.").setVersion(1110); addNodeObject(filter, "Contrast Blur", s_node_blur_contrast, "Node_Blur_Contrast", [1, Node_Blur_Contrast],, "Blur only pixel of a similiar color."); addNodeObject(filter, "Shape Blur", s_node_shape_blur, "Node_Blur_Shape", [1, Node_Blur_Shape]).setVersion(11650); @@ -587,14 +587,14 @@ function __initNodes() { addNodeObject(filter, "Outline", s_node_border, "Node_Outline", [1, Node_Outline], ["border"], "Add border to the image."); addNodeObject(filter, "Glow", s_node_glow, "Node_Glow", [1, Node_Glow],, "Apply glow to the border of the image."); addNodeObject(filter, "Shadow", s_node_shadow, "Node_Shadow", [1, Node_Shadow],, "Apply shadow behind the image."); - addNodeObject(filter, "Bloom", s_node_bloom, "Node_Bloom", [1, Node_Bloom],, "Apply bloom effect, bluring and brighten the bright part of the image."); + addNodeObject(filter, "Bloom", s_node_bloom, "Node_Bloom", [1, Node_Bloom],, "Apply bloom effect, blurring and brighten the bright part of the image."); addNodeObject(filter, "Trail", s_node_trail, "Node_Trail", [1, Node_Trail],, "Blend animation by filling in the pixel 'in-between' two or more frames.").setVersion(1130); addNodeObject(filter, "Erode", s_node_erode, "Node_Erode", [1, Node_Erode],, "Remove pixel that are close to the border of the image."); addNodeObject(filter, "Corner", s_node_corner, "Node_Corner", [1, Node_Corner], ["round corner"], "Round out sharp corner of the image.").setVersion(1110); addNodeObject(filter, "Blobify", s_node_blobify, "Node_Blobify", [1, Node_Blobify]).setVersion(11650); addNodeObject(filter, "2D Light", s_node_2d_light, "Node_2D_light", [1, Node_2D_light],, "Apply different shaped light on the image."); addNodeObject(filter, "Cast Shadow", s_node_shadow_cast, "Node_Shadow_Cast", [1, Node_Shadow_Cast], ["raycast"], "Apply light that create shadow using shadow mask.").setVersion(1100); - addNodeObject(filter, "Pixel Expand", s_node_atlas, "Node_Atlas", [1, Node_Atlas], ["atlas"], "Replace transparent pixel with the closet non-transparent pixel."); + addNodeObject(filter, "Pixel Expand", s_node_atlas, "Node_Atlas", [1, Node_Atlas], ["atlas"], "Replace transparent pixel with the closest non-transparent pixel."); addNodeObject(filter, "Pixel Cloud", s_node_pixel_cloud, "Node_Pixel_Cloud", [1, Node_Pixel_Cloud],, "Displace each pixel of the image randomly."); addNodeObject(filter, "Pixel Sort", s_node_pixel_sort, "Node_Pixel_Sort", [1, Node_Pixel_Sort],, "Sort pixel by brightness in horizontal, or vertial axis."); addNodeObject(filter, "Edge Detect", s_node_edge_detect, "Node_Edge_Detect", [1, Node_Edge_Detect],, "Edge detect by applying Sobel, Prewitt, or Laplacian kernel."); @@ -649,7 +649,7 @@ function __initNodes() { 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); - addNodeObject(d3d, "3D Camera Set", s_node_3d_camera_set, "Node_3D_Camera_Set", [1, Node_3D_Camera_Set],, "3D camera with build-in key and fill directional lights.").setVersion(11571); + addNodeObject(d3d, "3D Camera Set", s_node_3d_camera_set, "Node_3D_Camera_Set", [1, Node_3D_Camera_Set],, "3D camera with built-in key and fill directional lights.").setVersion(11571); 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); @@ -751,6 +751,9 @@ function __initNodes() { addNodeObject(generator, "Region Fill", s_node_region_fill, "Node_Region_Fill", [1, Node_Region_Fill],, "Fill connected pixel with colors.").setVersion(1147); addNodeObject(generator, "Flood Fill", s_node_flood_fill, "Node_Flood_Fill", [1, Node_Flood_Fill],, "Filled connected pixel given position and color.").setVersion(1133); + ds_list_add(generator, "Ray March"); + /**/addNodeObject(generator, "RM Primitive", s_node_mk_rain, "Node_RM_Primitive", [1, Node_RM_Primitive]).setVersion(11720); + ds_list_add(generator, "MK Effects"); addNodeObject(generator, "MK Rain", s_node_mk_rain, "Node_MK_Rain", [1, Node_MK_Rain]).setVersion(11600); addNodeObject(generator, "MK GridBalls", s_node_mk_ball_grid, "Node_MK_GridBalls", [1, Node_MK_GridBalls]).setVersion(11600); diff --git a/scripts/node_rm_primitive/node_outline.yy b/scripts/node_rm_primitive/node_outline.yy new file mode 100644 index 000000000..86468bc09 --- /dev/null +++ b/scripts/node_rm_primitive/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_rm_primitive/node_rm_primitive.gml b/scripts/node_rm_primitive/node_rm_primitive.gml new file mode 100644 index 000000000..d8d765fdc --- /dev/null +++ b/scripts/node_rm_primitive/node_rm_primitive.gml @@ -0,0 +1,27 @@ +function Node_RM_Primitive(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "RM Sphere"; + + inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF) + .setDisplay(VALUE_DISPLAY.vector); + + outputs[| 0] = nodeValue("Surface Out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_base_length = ds_list_size(inputs); + input_display_list = [ 0 ]; + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} + + static step = function() {} + + static processData = function(_outSurf, _data, _output_index, _array_index = 0) { + var _dim = _data[0]; + _outSurf = surface_verify(_outSurf, _dim[0], _dim[1]); + + surface_set_shader(_outSurf, sh_rm_primitive); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, _dim[0], _dim[1]); + surface_reset_shader(); + + return _outSurf; + } +} \ No newline at end of file diff --git a/scripts/node_rm_primitive/node_rm_primitive.yy b/scripts/node_rm_primitive/node_rm_primitive.yy new file mode 100644 index 000000000..ad982df32 --- /dev/null +++ b/scripts/node_rm_primitive/node_rm_primitive.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"node_rm_primitive", + "isCompatibility":false, + "isDnD":false, + "name":"node_rm_primitive", + "parent":{ + "name":"ray march", + "path":"folders/nodes/data/generator/ray march.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/node_scatter/node_scatter.gml b/scripts/node_scatter/node_scatter.gml index a0b8d5fb9..4dbc5f193 100644 --- a/scripts/node_scatter/node_scatter.gml +++ b/scripts/node_scatter/node_scatter.gml @@ -119,6 +119,9 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c inputs[| 37] = nodeValue("Exact", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) + inputs[| 38] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ "After", "Between", "Around" ]); + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) @@ -128,7 +131,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c input_display_list = [ 10, ["Surfaces", true], 0, 1, 15, 24, 25, 26, 27, ["Scatter", false], 6, 5, 13, 14, 17, 9, 31, 2, 30, 35, - ["Path", false], 19, 20, 21, 22, + ["Path", false], 19, 38, 20, 21, 22, ["Position", false], 33, 36, 37, ["Rotation", false], 7, 4, 32, ["Scale", false], 3, 8, 34, @@ -175,6 +178,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c var _sct = getInputData(9); var _arr = getInputData(15); var _amn = getInputData(26); + var _spa = getInputData(38); update_on_frame = _arr && (_amn[0] != 0 || _amn[1] != 0); @@ -186,8 +190,9 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c inputs[| 9].setVisible(_dis != 2 && _dis != 3); inputs[| 19].setVisible(_dis == 4, _dis == 4); inputs[| 20].setVisible(_dis == 4); - inputs[| 21].setVisible(_dis == 4); + inputs[| 21].setVisible(_dis == 4 && _spa == 0); inputs[| 22].setVisible(_dis == 4); + inputs[| 38].setVisible(_dis == 4 && _sct == 0); inputs[| 24].setVisible(_arr == 3, _arr == 3); inputs[| 25].setVisible(_arr == 4, _arr == 4); inputs[| 26].setVisible(_arr); @@ -224,6 +229,8 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c inputs[| 11].mappableStep(); } #endregion + ////=========== PROCESS =========== + static processData = function(_outSurf, _data, _output_index, _array_index) { #region if(_output_index == 1) return scatter_data; @@ -275,6 +282,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c var cirRng = _data[35]; var posShf = _data[36]; var posExt = _data[37]; + var pthSpac = _data[38]; var _in_w, _in_h; @@ -436,7 +444,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c case NODE_SCATTER_DIST.map : sp = array_safe_get_fast(_posDist, i); if(!is_array(sp)) continue; - + _x = _area[0] + _area[2] * (sp[0] * 2 - 1.); _y = _area[1] + _area[3] * (sp[1] * 2 - 1.); break; @@ -444,16 +452,35 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c case NODE_SCATTER_DIST.data : sp = array_safe_get_fast(_distData, i); if(!is_array(sp)) continue; - + _x = array_safe_get_fast(sp, 0); _y = array_safe_get_fast(sp, 1); _v = array_safe_get_fast(sp, 2, noone); break; case NODE_SCATTER_DIST.path : - _pathProgress = _scat? random(1) : i / max(1, _pre_amount); - _pathProgress = frac((_pathProgress + pathShf) * 0.9999); - + if(_scat == 0) { + switch(pthSpac) { + case 0 : + _pathProgress = i / max(1, _pre_amount); + _pathProgress = frac(_pathProgress + pathShf); + break; + + case 1 : + _pathProgress = i / max(1, _pre_amount - 1); + break; + + case 2 : + _pathProgress = (i + 0.5) / max(1, _pre_amount); + break; + + } + + } else { + _pathProgress = random(1); + _pathProgress = frac(_pathProgress + pathShf); + } + var pp = path.getPointRatio(_pathProgress, path_line_index); _x = pp.x + random_range(-pathDis, pathDis); _y = pp.y + random_range(-pathDis, pathDis); @@ -497,8 +524,11 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c _r *= _v; if(_dist == NODE_SCATTER_DIST.path && pathRot) { - var p0 = path.getPointRatio(clamp(_pathProgress - 0.001, 0, 0.9999), path_line_index); - var p1 = path.getPointRatio(clamp(_pathProgress + 0.001, 0, 0.9999), path_line_index); + var pr1 = clamp(_pathProgress + 0.01, 0, 1); + var pr0 = pr1 - 0.02; + + var p0 = path.getPointRatio(pr0, path_line_index); + var p1 = path.getPointRatio(pr1, path_line_index); var dirr = point_direction(p0.x, p0.y, p1.x, p1.y); _r += dirr; diff --git a/scripts/node_smoke_domain_queue/node_smoke_domain_queue.gml b/scripts/node_smoke_domain_queue/node_smoke_domain_queue.gml index 89584c699..89d382b0f 100644 --- a/scripts/node_smoke_domain_queue/node_smoke_domain_queue.gml +++ b/scripts/node_smoke_domain_queue/node_smoke_domain_queue.gml @@ -1,6 +1,6 @@ function Node_Smoke_Domain_Queue(_x, _y, _group = noone) : Node_Smoke(_x, _y, _group) constructor { name = "Queue Domain"; - setDimension(96, 48);; + setDimension(96, 48); manual_ungroupable = false; @@ -13,36 +13,12 @@ function Node_Smoke_Domain_Queue(_x, _y, _group = noone) : Node_Smoke(_x, _y, _g .setVisible(true, true); return inputs[| index]; - } - if(!LOADING && !APPENDING) createNewInput(); + } - static refreshDynamicInput = function() { - var _l = ds_list_create(); - - for( var i = 0; i < ds_list_size(inputs); i++ ) { - if(inputs[| i].value_from) - ds_list_add(_l, inputs[| i]); - else - delete inputs[| i]; - } - - for( var i = 0; i < ds_list_size(_l); i++ ) - _l[| i].index = i; - - ds_list_destroy(inputs); - inputs = _l; - - createNewInput(); - } - - static onValueFromUpdate = function(index) { - if(LOADING || APPENDING) return; - - refreshDynamicInput(); - } + setDynamicInput(1, true, VALUE_TYPE.sdomain); static update = function() { - for( var i = 0; i < ds_list_size(inputs) - 1; i++ ) { + for( var i = 0; i < ds_list_size(inputs); i++ ) { var _dom = getInputData(i); if(_dom != noone && instance_exists(_dom)) outputs[| 0].setValue(_dom); @@ -51,7 +27,6 @@ function Node_Smoke_Domain_Queue(_x, _y, _group = noone) : Node_Smoke(_x, _y, _g static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { var bbox = drawGetBbox(xx, yy, _s); - draw_sprite_fit(s_node_smokeSim_domain_queue, 0, bbox.xc, bbox.yc, bbox.w, bbox.h); } } \ No newline at end of file diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 044647c2c..1ec596bac 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -216,6 +216,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru con_index = -1; #endregion + /////============= META ============= + static setDummy = function(get_node) { #region is_dummy = true; dummy_get = get_node; @@ -223,27 +225,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return self; } #endregion - static setDefault = function(vals) { #region - if(LOADING || APPENDING) return self; - - ds_list_clear(animator.values); - for( var i = 0, n = array_length(vals); i < n; i++ ) - ds_list_add(animator.values, new valueKey(vals[i][0], vals[i][1], animator)); - - return self; - } #endregion - - static getName = function() { #region - if(name_custom) return name; - return __txt_junction_name(instanceof(node), connect_type, index, name); - } #endregion - - static setName = function(_name) { #region - INLINE - name = _name; - return self; - } #endregion - static setActive = function(_active, _tooltip) { #region INLINE active = _active; @@ -259,6 +240,51 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return self; } #endregion + static nonValidate = function() { #region + validateValue = false; + return self; + } #endregion + + static nonForward = function() { #region + forward = false; + return self; + } #endregion + + /////============= NAME ============= + + static getName = function() { #region + if(name_custom) return name; + return __txt_junction_name(instanceof(node), connect_type, index, name); + } #endregion + + static setName = function(_name) { #region + INLINE + name = _name; + return self; + } #endregion + + /////============= VALUE ============ + + static setType = function(_type) { #region + if(type == _type) return false; + + type = _type; + draw_junction_index = type; + updateColor(); + + return true; + } #endregion + + static setDefault = function(vals) { #region + if(LOADING || APPENDING) return self; + + ds_list_clear(animator.values); + for( var i = 0, n = array_length(vals); i < n; i++ ) + ds_list_add(animator.values, new valueKey(vals[i][0], vals[i][1], animator)); + + return self; + } #endregion + static resetValue = function() { #region unit.mode = def_unit; setValue(unit.apply(variable_clone(def_val))); @@ -276,40 +302,11 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return self; } #endregion - static setVisible = function(inspector) { #region - if(connect_type == JUNCTION_CONNECT.input) { - show_in_inspector = inspector; - visible = argument_count > 1? argument[1] : visible; - } else - visible = inspector; - node.will_setHeight = true; - - return self; - } #endregion - - static setDisplay = function(_type = VALUE_DISPLAY._default, _data = {}) { #region - display_type = _type; - display_data = _data; - resetDisplay(); - - return self; - } #endregion - - static setAnimable = function(_anim) { #region - animable = _anim; - return self; - } #endregion - static rejectArray = function() { #region accept_array = false; return self; } #endregion - static uncache = function() { #region - use_cache = false; - return self; - } #endregion - static setArrayDepth = function(aDepth) { #region array_depth = aDepth; return self; @@ -320,32 +317,11 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return self; } #endregion - static rejectConnect = function() { #region - auto_connect = false; - return self; - } #endregion - static rejectArrayProcess = function() { #region process_array = false; return self; } #endregion - static nonForward = function() { #region - forward = false; - return self; - } #endregion - - static nonValidate = function() { #region - validateValue = false; - return self; - } #endregion - - static isAnimable = function() { #region - if(type == VALUE_TYPE.PCXnode) return false; - if(display_type == VALUE_DISPLAY.text_array) return false; - return animable; - } #endregion - static setDropKey = function() { #region switch(type) { case VALUE_TYPE.integer : drop_key = "Number"; break; @@ -368,6 +344,133 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } setDropKey(); #endregion + static setMappable = function(index) { #region + attributes.mapped = false; + attributes.map_index = index; + + mapButton = button(function() { + attributes.mapped = !attributes.mapped; + var val = getValue(); + if( attributes.mapped && is_numeric(val)) setValue([0, val]); + if(!attributes.mapped && is_array(val)) setValue(array_safe_get_fast(val, 0)); + setArrayDepth(attributes.mapped); + + node.triggerRender(); + }) + .setIcon( THEME.value_use_surface, [ function() { return attributes.mapped; } ], COLORS._main_icon ) + .setTooltip("Toggle map"); + + switch(type) { + case VALUE_TYPE.gradient : + mapWidget = noone; + break; + + default : + mapWidget = new rangeBox(TEXTBOX_INPUT.number, function(index, val) { return setValueDirect(val, index); }); + mapWidget.side_button = mapButton; + break; + } + + editWidget.side_button = mapButton; + + return self; + } #endregion + + static setMapped = function(junc) { #region + mappedJunc = junc; + isTimelineVisible = function() { INLINE return is_anim && value_from == noone && mappedJunc.attributes.mapped; } + return self; + } #endregion + + static mappableStep = function() { #region + editWidget = mapWidget && attributes.mapped? mapWidget : editWidgetRaw; + setArrayDepth(attributes.mapped); + + var inp = node.inputs[| attributes.map_index]; + var vis = attributes.mapped && show_in_inspector; + + if(inp.visible != vis) { + inp.visible = vis; + node.refreshNodeDisplay(); + } + } #endregion + + /////========== ANIMATION ========== + + static setAnimable = function(_anim) { #region + animable = _anim; + return self; + } #endregion + + static isAnimable = function() { #region + if(type == VALUE_TYPE.PCXnode) return false; + if(display_type == VALUE_DISPLAY.text_array) return false; + return animable; + } #endregion + + static setAnim = function(anim, record = false) { #region + if(is_anim == anim) return; + if(record) { + recordAction(ACTION_TYPE.custom, function(data) { + setAnim(data.is_anim); + data.is_anim = !data.is_anim; + }, { anim: is_anim }); + } + is_anim = anim; + + if(is_anim) { + if(ds_list_empty(animator.values)) + ds_list_add(animator.values, new valueKey(CURRENT_FRAME, animator.getValue(), animator)); + animator.values[| 0].time = CURRENT_FRAME; + animator.updateKeyMap(); + + for( var i = 0, n = array_length(animators); i < n; i++ ) { + if(ds_list_empty(animators[i].values)) + ds_list_add(animators[i].values, new valueKey(CURRENT_FRAME, animators[i].getValue(), animators[i])); + animators[i].values[| 0].time = CURRENT_FRAME; + animators[i].updateKeyMap(); + } + } else { + var _val = animator.getValue(); + ds_list_clear(animator.values); + animator.values[| 0] = new valueKey(0, _val, animator); + animator.updateKeyMap(); + + for( var i = 0, n = array_length(animators); i < n; i++ ) { + var _val = animators[i].getValue(); + ds_list_clear(animators[i].values); + animators[i].values[| 0] = new valueKey(0, _val, animators[i]); + animators[i].updateKeyMap(); + } + } + + if(type == VALUE_TYPE.gradient && struct_has(attributes, "map_index")) + node.inputs[| attributes.map_index + 1].setAnim(anim); + + node.refreshTimeline(); + } #endregion + + /////============ DISPLAY =========== + + static setVisible = function(inspector) { #region + if(connect_type == JUNCTION_CONNECT.input) { + show_in_inspector = inspector; + visible = argument_count > 1? argument[1] : visible; + } else + visible = inspector; + node.will_setHeight = true; + + return self; + } #endregion + + static setDisplay = function(_type = VALUE_DISPLAY._default, _data = {}) { #region + display_type = _type; + display_data = _data; + resetDisplay(); + + return self; + } #endregion + static resetDisplay = function() { #region //////////////////// RESET DISPLAY //////////////////// editWidget = noone; switch(display_type) { @@ -803,169 +906,51 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru updateColor(); } resetDisplay(); #endregion - static setMappable = function(index) { #region - attributes.mapped = false; - attributes.map_index = index; + /////============ RENDER ============ + + static isRendered = function() { #region + if(type == VALUE_TYPE.node) return true; - mapButton = button(function() { - attributes.mapped = !attributes.mapped; - var val = getValue(); - if( attributes.mapped && is_numeric(val)) setValue([0, val]); - if(!attributes.mapped && is_array(val)) setValue(array_safe_get_fast(val, 0)); - setArrayDepth(attributes.mapped); - - node.triggerRender(); - }) - .setIcon( THEME.value_use_surface, [ function() { return attributes.mapped; } ], COLORS._main_icon ) - .setTooltip("Toggle map"); + if(value_from == noone) return true; - switch(type) { - case VALUE_TYPE.gradient : - mapWidget = noone; - break; - - default : - mapWidget = new rangeBox(TEXTBOX_INPUT.number, function(index, val) { return setValueDirect(val, index); }); - mapWidget.side_button = mapButton; - break; - } + var controlNode = value_from.from? value_from.from : value_from.node; + if(!controlNode.active) return true; + if(!controlNode.isRenderActive()) return true; - editWidget.side_button = mapButton; - - return self; + return controlNode.rendered; } #endregion - static setMapped = function(junc) { #region - mappedJunc = junc; - isTimelineVisible = function() { INLINE return is_anim && value_from == noone && mappedJunc.attributes.mapped; } - return self; - } #endregion - - static mappableStep = function() { #region - editWidget = mapWidget && attributes.mapped? mapWidget : editWidgetRaw; - setArrayDepth(attributes.mapped); - - var inp = node.inputs[| attributes.map_index]; - var vis = attributes.mapped && show_in_inspector; - - if(inp.visible != vis) { - inp.visible = vis; - node.refreshNodeDisplay(); - } - } #endregion - - static setColor = function(col) { #region - color = col; - updateColor(); - - if(value_from != noone) - value_from.setColor(col); - - return self; - } #endregion - - static updateColor = function(val = undefined) { #region + static isActiveDynamic = function(frame = CURRENT_FRAME) { #region INLINE - if(color == -1) { - draw_bg = isArray(val)? value_color_bg_array(draw_junction_index) : value_color_bg(draw_junction_index); - draw_fg = value_color(draw_junction_index); - } else { - draw_bg = isArray(val)? merge_color(color, colorMultiply(color, CDEF.main_dkgrey), 0.5) : value_color_bg(draw_junction_index); - draw_fg = color; + if(value_from_loop) return true; + if(value_from != noone) return false; + + if(expUse) { + if(!is_struct(expTree)) return false; + var res = expTree.isDynamic(); + + switch(res) { + case EXPRESS_TREE_ANIM.none : return false; + case EXPRESS_TREE_ANIM.base_value : force_requeue = true; return is_anim; + case EXPRESS_TREE_ANIM.animated : force_requeue = true; return true; + } } - color_display = type == VALUE_TYPE.action? #8fde5d : draw_fg; - + return is_anim; } #endregion - static setType = function(_type) { #region - if(type == _type) return false; - - type = _type; - draw_junction_index = type; - updateColor(); - - return true; - } #endregion + /////============= CACHE ============ - static setUseExpression = function(useExp) { #region - INLINE - if(expUse == useExp) return; - expUse = useExp; - node.triggerRender(); - } #endregion - - static setExpression = function(_expression) { #region - expUse = true; - expression = _expression; - expressionUpdate(); - } #endregion - - static expressionUpdate = function() { #region - expTree = evaluateFunctionList(expression); - resetCache(); - node.triggerRender(); - } #endregion - - static onValidate = function() { #region - if(!validateValue) return; - var _val = value_validation, str = ""; - value_validation = VALIDATION.pass; - - switch(type) { - case VALUE_TYPE.path: - switch(display_type) { - case VALUE_DISPLAY.path_load: - var path = animator.getValue(); - if(is_array(path)) path = path[0]; - - if(!is_string(path) || path == "") { - str = $"Path invalid: {path}"; - break; - } - - if(path_get(path) == -1) { - value_validation = VALIDATION.error; - str = $"File not exist: {path}"; - } - break; - case VALUE_DISPLAY.path_array: - var paths = animator.getValue(); - if(is_array(paths)) { - for( var i = 0, n = array_length(paths); i < n; i++ ) { - if(path_get(paths[i]) != -1) continue; - value_validation = VALIDATION.error; - str = "File not exist: " + string(paths[i]); - } - } else { - value_validation = VALIDATION.error; - str = "File not exist: " + string(paths); - } - break; - } - break; - } - - node.onValidate(); - - if(_val == value_validation) return self; - - #region notification - if(value_validation == VALIDATION.error && error_notification == noone) { - error_notification = noti_error(str); - error_notification.onClick = function() { PANEL_GRAPH.focusNode(node); }; - } - - if(value_validation == VALIDATION.pass && error_notification != noone) { - noti_remove(error_notification); - error_notification = noone; - } - #endregion - + static uncache = function() { #region + use_cache = false; return self; } #endregion + static resetCache = function() { cache_value[0] = false; } + + /////============== GET ============= + static valueProcess = function(value, nodeFrom, applyUnit = true, arrIndex = 0) { #region var typeFrom = nodeFrom.type; @@ -1084,8 +1069,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return value; } #endregion - 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 ////Get value @@ -1297,70 +1280,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return animator.getValue(_time); } #endregion - static setAnim = function(anim, record = false) { #region - if(is_anim == anim) return; - if(record) { - recordAction(ACTION_TYPE.custom, function(data) { - setAnim(data.is_anim); - data.is_anim = !data.is_anim; - }, { anim: is_anim }); - } - is_anim = anim; - - if(is_anim) { - if(ds_list_empty(animator.values)) - ds_list_add(animator.values, new valueKey(CURRENT_FRAME, animator.getValue(), animator)); - animator.values[| 0].time = CURRENT_FRAME; - animator.updateKeyMap(); - - for( var i = 0, n = array_length(animators); i < n; i++ ) { - if(ds_list_empty(animators[i].values)) - ds_list_add(animators[i].values, new valueKey(CURRENT_FRAME, animators[i].getValue(), animators[i])); - animators[i].values[| 0].time = CURRENT_FRAME; - animators[i].updateKeyMap(); - } - } else { - var _val = animator.getValue(); - ds_list_clear(animator.values); - animator.values[| 0] = new valueKey(0, _val, animator); - animator.updateKeyMap(); - - for( var i = 0, n = array_length(animators); i < n; i++ ) { - var _val = animators[i].getValue(); - ds_list_clear(animators[i].values); - animators[i].values[| 0] = new valueKey(0, _val, animators[i]); - animators[i].updateKeyMap(); - } - } - - if(type == VALUE_TYPE.gradient && struct_has(attributes, "map_index")) - node.inputs[| attributes.map_index + 1].setAnim(anim); - - node.refreshTimeline(); - } #endregion - static isTimelineVisible = function() { INLINE return is_anim && value_from == noone; } - static isActiveDynamic = function(frame = CURRENT_FRAME) { #region - INLINE - - if(value_from_loop) return true; - if(value_from != noone) return false; - - if(expUse) { - if(!is_struct(expTree)) return false; - var res = expTree.isDynamic(); - - switch(res) { - case EXPRESS_TREE_ANIM.none : return false; - case EXPRESS_TREE_ANIM.base_value : force_requeue = true; return is_anim; - case EXPRESS_TREE_ANIM.animated : force_requeue = true; return true; - } - } - - return is_anim; - } #endregion - show_val = []; static showValue = function() { #region ////showValue INLINE @@ -1381,6 +1302,18 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return val; } #endregion + static getShowString = function() { #region + var val = showValue(); + return string_real(val); + } #endregion + + static unitConvert = function(mode) { #region + var _v = animator.values; + + for( var i = 0; i < ds_list_size(_v); i++ ) + _v[| i].value = unit.convertUnit(_v[| i].value, mode); + } #endregion + static isDynamicArray = function() { #region if(dynamic_array) return true; @@ -1443,6 +1376,66 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return array_length(ar); } #endregion + /////============== SET ============= + + static onValidate = function() { #region + if(!validateValue) return; + var _val = value_validation, str = ""; + value_validation = VALIDATION.pass; + + switch(type) { + case VALUE_TYPE.path: + switch(display_type) { + case VALUE_DISPLAY.path_load: + var path = animator.getValue(); + if(is_array(path)) path = path[0]; + + if(!is_string(path) || path == "") { + str = $"Path invalid: {path}"; + break; + } + + if(path_get(path) == -1) { + value_validation = VALIDATION.error; + str = $"File not exist: {path}"; + } + break; + case VALUE_DISPLAY.path_array: + var paths = animator.getValue(); + if(is_array(paths)) { + for( var i = 0, n = array_length(paths); i < n; i++ ) { + if(path_get(paths[i]) != -1) continue; + value_validation = VALIDATION.error; + str = "File not exist: " + string(paths[i]); + } + } else { + value_validation = VALIDATION.error; + str = "File not exist: " + string(paths); + } + break; + } + break; + } + + node.onValidate(); + + if(_val == value_validation) return self; + + #region notification + if(value_validation == VALIDATION.error && error_notification == noone) { + error_notification = noti_error(str); + error_notification.onClick = function() { PANEL_GRAPH.focusNode(node); }; + } + + if(value_validation == VALIDATION.pass && error_notification != noone) { + noti_remove(error_notification); + error_notification = noone; + } + #endregion + + return self; + } #endregion + static setValue = function(val = 0, record = true, time = CURRENT_FRAME, _update = true) { #region ////Set value val = unit.invApply(val); return setValueDirect(val, noone, record, time, _update); @@ -1556,6 +1549,51 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return true; } #endregion + static setString = function(str) { #region + if(connect_type == JUNCTION_CONNECT.output) return; + var _o = animator.getValue(); + + if(string_pos(",", str) > 0) { + string_replace(str, "[", ""); + string_replace(str, "]", ""); + + var ss = str, pos, val = [], ind = 0; + + while(string_length(ss) > 0) { + pos = string_pos(",", ss); + + if(pos == 0) { + val[ind++] = toNumber(ss); + ss = ""; + } else { + val[ind++] = toNumber(string_copy(ss, 1, pos - 1)); + ss = string_copy(ss, pos + 1, string_length(ss) - pos); + } + } + + var _t = typeArray(display_type); + if(_t) { + if(array_length(_o) == array_length(val) || _t == 2) + setValue(val); + } else if(array_length(val) > 0) { + setValue(val[0]); + } + } else { + if(is_array(_o)) { + setValue(array_create(array_length(_o), toNumber(str))); + } else { + setValue(toNumber(str)); + } + } + } #endregion + + /////=========== CONNECT =========== + + static rejectConnect = function() { #region + auto_connect = false; + return self; + } #endregion + static isConnectable = function(_valueFrom, checkRecur = true, log = false) { #region if(_valueFrom == -1 || _valueFrom == undefined || _valueFrom == noone) { if(log) noti_warning($"LOAD: Cannot set node connection from {_valueFrom} to {name} of node {node.name}.",, node); @@ -1605,22 +1643,10 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return 1; } #endregion - static isRendered = function() { #region - if(type == VALUE_TYPE.node) return true; - - if(value_from == noone) return true; - - var controlNode = value_from.from? value_from.from : value_from.node; - if(!controlNode.active) return true; - if(!controlNode.isRenderActive()) return true; - - return controlNode.rendered; - } #endregion - static triggerSetFrom = function() { node.valueUpdate(index); } static setFrom = function(_valueFrom, _update = true, checkRecur = true, log = false) { #region ////Set from - //print($"Connecting {_valueFrom.name} to {name}"); + // print($"Connecting {_valueFrom.name} to {name}"); if(is_dummy) { var _targ = dummy_get(); @@ -1699,49 +1725,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru PROJECT.modified = true; } #endregion - static getShowString = function() { #region - var val = showValue(); - return string_real(val); - } #endregion - - static setString = function(str) { #region - if(connect_type == JUNCTION_CONNECT.output) return; - var _o = animator.getValue(); - - if(string_pos(",", str) > 0) { - string_replace(str, "[", ""); - string_replace(str, "]", ""); - - var ss = str, pos, val = [], ind = 0; - - while(string_length(ss) > 0) { - pos = string_pos(",", ss); - - if(pos == 0) { - val[ind++] = toNumber(ss); - ss = ""; - } else { - val[ind++] = toNumber(string_copy(ss, 1, pos - 1)); - ss = string_copy(ss, pos + 1, string_length(ss) - pos); - } - } - - var _t = typeArray(display_type); - if(_t) { - if(array_length(_o) == array_length(val) || _t == 2) - setValue(val); - } else if(array_length(val) > 0) { - setValue(val[0]); - } - } else { - if(is_array(_o)) { - setValue(array_create(array_length(_o), toNumber(str))); - } else { - setValue(toNumber(str)); - } - } - } #endregion - static checkConnection = function(_remove_list = true) { #region if(value_from == noone) return; if(value_from.node.active) return; @@ -1759,11 +1742,47 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return false; } #endregion - static unitConvert = function(mode) { #region - var _v = animator.values; + static hasJunctionFrom = function() { INLINE return value_from != noone || value_from_loop != noone; } + + static getJunctionTo = function() { #region + var _junc_to = []; + + for(var i = 0; i < array_length(value_to); i++) { + var _to = value_to[i]; + if(!_to.node.active || _to.value_from == noone) continue; + if(_to.value_from != self) continue; + + array_push(_junc_to, _to); + } + + return _junc_to; + } #endregion + + /////============= DRAW ============= + + static setColor = function(col) { #region + color = col; + updateColor(); + + if(value_from != noone) + value_from.setColor(col); + + return self; + } #endregion + + static updateColor = function(val = undefined) { #region + INLINE + + if(color == -1) { + draw_bg = isArray(val)? value_color_bg_array(draw_junction_index) : value_color_bg(draw_junction_index); + draw_fg = value_color(draw_junction_index); + } else { + draw_bg = isArray(val)? merge_color(color, colorMultiply(color, CDEF.main_dkgrey), 0.5) : value_color_bg(draw_junction_index); + draw_fg = color; + } + + color_display = type == VALUE_TYPE.action? #8fde5d : draw_fg; - for( var i = 0; i < ds_list_size(_v); i++ ) - _v[| i].value = unit.convertUnit(_v[| i].value, mode); } #endregion static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region @@ -1986,92 +2005,29 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return visible_in_list; } #endregion - static extractNode = function(_type = extract_node) { #region - if(_type == "") return noone; - - var ext = nodeBuild(_type, node.x, node.y); - ext.x -= ext.w + 32; - - for( var i = 0; i < ds_list_size(ext.outputs); i++ ) { - if(setFrom(ext.outputs[| i])) break; - } - - var animFrom = animator.values; - var len = 2; - - switch(_type) { - case "Node_Vector4": len++; - case "Node_Vector3": len++; - case "Node_Vector2": - for( var j = 0; j < len; j++ ) { - var animTo = ext.inputs[| j].animator; - var animLs = animTo.values; - - ext.inputs[| j].setAnim(is_anim); - ds_list_clear(animLs); - } - - for( var i = 0; i < ds_list_size(animFrom); i++ ) { - for( var j = 0; j < len; j++ ) { - var animTo = ext.inputs[| j].animator; - var animLs = animTo.values; - var a = animFrom[| i].clone(animTo); - - a.value = a.value[j]; - ds_list_add(animLs, a); - } - } - break; - case "Node_Path": - break; - default: - var animTo = ext.inputs[| 0].animator; - var animLs = animTo.values; - - ext.inputs[| 0].setAnim(is_anim); - ds_list_clear(animLs); - - for( var i = 0; i < ds_list_size(animFrom); i++ ) - ds_list_add(animLs, animFrom[| i].clone(animTo)); - break; - } - - ext.doUpdate(); + /////========== EXPRESSION ========== + + static setUseExpression = function(useExp) { #region + INLINE + if(expUse == useExp) return; + expUse = useExp; + node.triggerRender(); } #endregion - static hasJunctionFrom = function() { INLINE return value_from != noone; } - - static getJunctionTo = function() { #region - var _junc_to = []; - - for(var i = 0; i < array_length(value_to); i++) { - var _to = value_to[i]; - if(!_to.node.active || _to.value_from == noone) continue; - if(_to.value_from != self) continue; - - array_push(_junc_to, _to); - } - - return _junc_to; + static setExpression = function(_expression) { #region + expUse = true; + expression = _expression; + expressionUpdate(); } #endregion - static dragValue = function() { #region - if(drop_key == "None") return; - - DRAGGING = { - type: drop_key, - data: showValue(), - } - - if(type == VALUE_TYPE.path) { - DRAGGING.data = new FileObject(node.name, DRAGGING.data); - DRAGGING.data.getSpr(); - } - - if(connect_type == JUNCTION_CONNECT.input) - DRAGGING.from = self; + static expressionUpdate = function() { #region + expTree = evaluateFunctionList(expression); + resetCache(); + node.triggerRender(); } #endregion + /////=========== SERIALIZE =========== + static serialize = function(scale = false, preset = false) { #region var _map = {}; @@ -2223,6 +2179,78 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return false; } #endregion + /////============= MISC ============= + + static extractNode = function(_type = extract_node) { #region + if(_type == "") return noone; + + var ext = nodeBuild(_type, node.x, node.y); + ext.x -= ext.w + 32; + + for( var i = 0; i < ds_list_size(ext.outputs); i++ ) { + if(setFrom(ext.outputs[| i])) break; + } + + var animFrom = animator.values; + var len = 2; + + switch(_type) { + case "Node_Vector4": len++; + case "Node_Vector3": len++; + case "Node_Vector2": + for( var j = 0; j < len; j++ ) { + var animTo = ext.inputs[| j].animator; + var animLs = animTo.values; + + ext.inputs[| j].setAnim(is_anim); + ds_list_clear(animLs); + } + + for( var i = 0; i < ds_list_size(animFrom); i++ ) { + for( var j = 0; j < len; j++ ) { + var animTo = ext.inputs[| j].animator; + var animLs = animTo.values; + var a = animFrom[| i].clone(animTo); + + a.value = a.value[j]; + ds_list_add(animLs, a); + } + } + break; + case "Node_Path": + break; + default: + var animTo = ext.inputs[| 0].animator; + var animLs = animTo.values; + + ext.inputs[| 0].setAnim(is_anim); + ds_list_clear(animLs); + + for( var i = 0; i < ds_list_size(animFrom); i++ ) + ds_list_add(animLs, animFrom[| i].clone(animTo)); + break; + } + + ext.doUpdate(); + } #endregion + + static dragValue = function() { #region + if(drop_key == "None") return; + + DRAGGING = { + type: drop_key, + data: showValue(), + } + + if(type == VALUE_TYPE.path) { + DRAGGING.data = new FileObject(node.name, DRAGGING.data); + DRAGGING.data.getSpr(); + } + + if(connect_type == JUNCTION_CONNECT.input) + DRAGGING.from = self; + } #endregion + static destroy = function() { #region if(error_notification != noone) { noti_remove(error_notification); @@ -2230,13 +2258,13 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } #endregion - static cleanUp = function() { #region - - } #endregion + static cleanUp = function() {} static toString = function() { return (connect_type == JUNCTION_CONNECT.input? "Input" : "Output") + $" junction {index} of [{name}]: {node}"; } } +/////========== FUNCTIONS ========== + function drawJuncConnection(from, to, params) { #region #region parameters var log = params.log; diff --git a/scripts/panel_graph/panel_graph.gml b/scripts/panel_graph/panel_graph.gml index b361d9dad..dd7600743 100644 --- a/scripts/panel_graph/panel_graph.gml +++ b/scripts/panel_graph/panel_graph.gml @@ -1506,6 +1506,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { var junc_out = data.params.junc_out; var feed = nodeBuild("Node_Feedback_Inline", 0, 0); + // feed.connectJunctions(junc_in, junc_out); feed.attributes.junc_in = [ junc_in .node.node_id, junc_in .index ]; feed.attributes.junc_out = [ junc_out.node.node_id, junc_out.index ]; feed.scanJunc(); diff --git a/scripts/path_function/path_function.gml b/scripts/path_function/path_function.gml index 9b52c0e1f..e50007a13 100644 --- a/scripts/path_function/path_function.gml +++ b/scripts/path_function/path_function.gml @@ -1,3 +1,6 @@ +function eval_bezier_x(t, x0, y0, x1, y1, cx0, cy0, cx1, cy1) { INLINE return power(1 - t, 3) * x0 + 3 * power(1 - t, 2) * (t) * cx0 + 3 * power(t, 2) * (1 - t) * cx1 + power(t, 3) * x1; } +function eval_bezier_y(t, x0, y0, x1, y1, cx0, cy0, cx1, cy1) { INLINE return power(1 - t, 3) * y0 + 3 * power(1 - t, 2) * (t) * cy0 + 3 * power(t, 2) * (1 - t) * cy1 + power(t, 3) * y1; } + function eval_bezier(t, x0, y0, x1, y1, cx0, cy0, cx1, cy1) { var xx = power(1 - t, 3) * x0 + 3 * power(1 - t, 2) * (t) * cx0 + 3 * power(t, 2) * (1 - t) * cx1 + power(t, 3) * x1; var yy = power(1 - t, 3) * y0 + 3 * power(1 - t, 2) * (t) * cy0 + 3 * power(t, 2) * (1 - t) * cy1 + power(t, 3) * y1; diff --git a/shaders/sh_rm_primitive/sh_rm_primitive.fsh b/shaders/sh_rm_primitive/sh_rm_primitive.fsh new file mode 100644 index 000000000..7127a141b --- /dev/null +++ b/shaders/sh_rm_primitive/sh_rm_primitive.fsh @@ -0,0 +1,292 @@ +//Inigo Quilez +//Oh where would I be without you. + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +const int MAX_MARCHING_STEPS = 255; +const float MIN_DIST = 3.; +const float MAX_DIST = 6.; +const float EPSILON = .0001; + +#region ================ Transform ================ + mat3 rotateX(float dg) { + float c = cos(radians(dg)); + float s = sin(radians(dg)); + return mat3( + vec3(1, 0, 0), + vec3(0, c, -s), + vec3(0, s, c) + ); + } + + mat3 rotateY(float dg) { + float c = cos(radians(dg)); + float s = sin(radians(dg)); + return mat3( + vec3( c, 0, s), + vec3( 0, 1, 0), + vec3(-s, 0, c) + ); + } + + mat3 rotateZ(float dg) { + float c = cos(radians(dg)); + float s = sin(radians(dg)); + return mat3( + vec3(c, -s, 0), + vec3(s, c, 0), + vec3(0, 0, 1) + ); + } + + mat3 inverse(mat3 m) { + float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2]; + float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2]; + float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2]; + + float b01 = a22 * a11 - a12 * a21; + float b11 = -a22 * a10 + a12 * a20; + float b21 = a21 * a10 - a11 * a20; + + float det = a00 * b01 + a01 * b11 + a02 * b21; + + return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11), + b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10), + b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det; + } +#endregion + +#region ================ Primitives ================ + + float dot2( in vec2 v ) { return dot(v,v); } + float dot2( in vec3 v ) { return dot(v,v); } + float ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; } + + float sdPlane( vec3 p, vec3 n, float h ) { + // n must be normalized + return dot(p,n) + h; + } + + float sdBox( vec3 p, vec3 b ) { + vec3 q = abs(p) - b; + return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); + } + + float sdBoxFrame( vec3 p, vec3 b, float e ) { + p = abs(p)-b; + vec3 q = abs(p+e)-e; + return min(min( + length(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0), + length(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)), + length(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0)); + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + + float sdSphere(vec3 p) { + return length(p) - 1.0; + } + + float sdEllipsoid( vec3 p, vec3 r ) { + float k0 = length(p/r); + float k1 = length(p/(r*r)); + return k0*(k0-1.0)/k1; + } + + float sdTorus( vec3 p, vec2 t ) { + vec2 q = vec2(length(p.xz)-t.x,p.y); + return length(q)-t.y; + } + + float sdCutSphere( vec3 p, float r, float h ) { + // sampling independent computations (only depend on shape) + float w = sqrt(r*r-h*h); + + // sampling dependant computations + vec2 q = vec2( length(p.xz), p.y ); + float s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y ); + return (s<0.0) ? length(q)-r : + (q.xsc.x*p.y) ? dot(p.xy,sc) : length(p.xy); + return sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb; + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + + float sdCylinder( vec3 p, vec3 c ) { + return length(p.xz-c.xy)-c.z; + } + + float sdCappedCylinder( vec3 p, float h, float r ) { + vec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h); + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); + } + + float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) { + vec3 pa = p - a, ba = b - a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length( pa - ba*h ) - r; + } + + float sdCone( vec3 p, vec2 c, float h ) { + // c is the sin/cos of the angle, h is height + // Alternatively pass q instead of (c,h), + // which is the point at the base in 2D + vec2 q = h*vec2(c.x/c.y,-1.0); + + vec2 w = vec2( length(p.xz), p.y ); + vec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 ); + vec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 ); + float k = sign( q.y ); + float d = min(dot( a, a ),dot(b, b)); + float s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) ); + return sqrt(d)*sign(s); + } + + float sdCappedCone( vec3 p, float h, float r1, float r2 ) { + vec2 q = vec2( length(p.xz), p.y ); + vec2 k1 = vec2(r2,h); + vec2 k2 = vec2(r2-r1,2.0*h); + vec2 ca = vec2(q.x-min(q.x,(q.y<0.0)?r1:r2), abs(q.y)-h); + vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot2(k2), 0.0, 1.0 ); + float s = (cb.x<0.0 && ca.y<0.0) ? -1.0 : 1.0; + return s*sqrt( min(dot2(ca),dot2(cb)) ); + } + + float sdRoundCone( vec3 p, float r1, float r2, float h ) { + // sampling independent computations (only depend on shape) + float b = (r1-r2)/h; + float a = sqrt(1.0-b*b); + + // sampling dependant computations + vec2 q = vec2( length(p.xz), p.y ); + float k = dot(q,vec2(-b,a)); + if( k<0.0 ) return length(q) - r1; + if( k>a*h ) return length(q-vec2(0.0,h)) - r2; + return dot(q, vec2(a,b) ) - r1; + } + + float sdSolidAngle( vec3 p, vec2 c, float ra ) { + // c is the sin/cos of the angle + vec2 q = vec2( length(p.xz), p.y ); + float l = length(q) - ra; + float m = length(q - c*clamp(dot(q,c),0.0,ra) ); + return max(l,m*sign(c.y*q.x-c.x*q.y)); + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + + float sdOctahedron( vec3 p, float s ) { + p = abs(p); + float m = p.x+p.y+p.z-s; + vec3 q; + if( 3.0*p.x < m ) q = p.xyz; + else if( 3.0*p.y < m ) q = p.yzx; + else if( 3.0*p.z < m ) q = p.zxy; + else return m*0.57735027; + + float k = clamp(0.5*(q.z-q.y+s),0.0,s); + return length(vec3(q.x,q.y-s+k,q.z-k)); + } + + float sdPyramid( vec3 p, float h ) { + float m2 = h*h + 0.25; + + p.xz = abs(p.xz); + p.xz = (p.z>p.x) ? p.zx : p.xz; + p.xz -= 0.5; + + vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); + + float s = max(-q.x,0.0); + float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); + + float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; + float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); + + float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); + + return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y)); + } +#endregion + +float sceneSDF(vec3 p) { + float d; + mat3 rx = rotateX(45.); + mat3 ry = rotateY(45.); + + p = inverse(rx * ry) * p; + + // d = sdSphere(p); + // d = sdBox(p, vec3(.5)); + d = sdBoxFrame(p, vec3(.5), 0.1); + + return d; +} + +vec3 normal(vec3 p) { + return normalize(vec3( + sceneSDF(vec3(p.x + EPSILON, p.y, p.z)) - sceneSDF(vec3(p.x - EPSILON, p.y, p.z)), + sceneSDF(vec3(p.x, p.y + EPSILON, p.z)) - sceneSDF(vec3(p.x, p.y - EPSILON, p.z)), + sceneSDF(vec3(p.x, p.y, p.z + EPSILON)) - sceneSDF(vec3(p.x, p.y, p.z - EPSILON)) + )); +} + +float march(vec3 camera, vec3 direction) { + float depth = MIN_DIST; + + for (int i = 0; i < MAX_MARCHING_STEPS; i++) { + float dist = sceneSDF(camera + depth * direction); + if (dist < EPSILON) + return depth; + + depth += dist; + if (depth >= MAX_DIST) + return MAX_DIST; + } + + return MAX_DIST; +} + +void main() { + float z = 1. / tan(radians(30.) / 2.); + vec3 dir = normalize(vec3((v_vTexcoord - .5) * 2., -z)); + vec3 eye = vec3(0., 0., 5.); + float dist = march(eye, dir); + + if(dist > MAX_DIST - EPSILON) { + gl_FragColor = vec4(0., 0., 0., 1.); + return; + } + + vec3 c = vec3(1.); + + float distNorm = 1. - (dist - MIN_DIST) / (MAX_DIST - MIN_DIST); + distNorm = smoothstep(.0, .3, distNorm) + .2; + c *= vec3(distNorm); + + vec3 coll = eye + dir * dist; + vec3 norm = normal(coll); + vec3 light = normalize(vec3(-0.5, -0.5, 1.)); + float lamo = dot(norm, light) + 0.2; + + c *= lamo; + + gl_FragColor = vec4(c, 1.); +} \ No newline at end of file diff --git a/shaders/sh_rm_primitive/sh_rm_primitive.vsh b/shaders/sh_rm_primitive/sh_rm_primitive.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_rm_primitive/sh_rm_primitive.vsh @@ -0,0 +1,19 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() +{ + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_rm_primitive/sh_rm_primitive.yy b/shaders/sh_rm_primitive/sh_rm_primitive.yy new file mode 100644 index 000000000..5ceea7a0f --- /dev/null +++ b/shaders/sh_rm_primitive/sh_rm_primitive.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_rm_primitive", + "name":"sh_rm_primitive", + "parent":{ + "name":"ray march", + "path":"folders/shader/ray march.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file