From 23dc656b888d3983141a8da6f4bb5c04dc040de5 Mon Sep 17 00:00:00 2001
From: tamat
Date: Fri, 23 Oct 2015 16:10:44 +0200
Subject: [PATCH] added remove slot option
---
LICENSE | 0
README.md | 0
build/litegraph.js | 262 ++++++++++++++++----
build/litegraph.min.js | 105 ++++----
css/litegraph-editor.css | 0
css/litegraph.css | 0
demo/code.js | 0
demo/code_old.js | 0
demo/demo.js | 0
demo/demodata/video.webm | Bin
demo/imgs/grid.png | Bin
demo/imgs/icon-edit.png | Bin
demo/imgs/icon-gear.png | Bin
demo/imgs/icon-load.png | Bin
demo/imgs/icon-maximize.png | Bin
demo/imgs/icon-play.png | Bin
demo/imgs/icon-playstep.png | Bin
demo/imgs/icon-record.png | Bin
demo/imgs/icon-save.png | Bin
demo/imgs/icon-stop.png | Bin
demo/imgs/load-progress-empty.png | Bin
demo/imgs/load-progress-full.png | Bin
demo/imgs/load-progress-grey.png | Bin
demo/imgs/play-icons-light-alpha.png | Bin
demo/imgs/play-icons-light.png | Bin
demo/imgs/play-icons.png | Bin
demo/index.html | 0
demo/style.css | 0
doc/api.js | 0
doc/assets/css/external-small.png | Bin
doc/assets/css/logo.png | Bin
doc/assets/css/main.css | 0
doc/assets/favicon.png | Bin
doc/assets/img/spinner.gif | Bin
doc/assets/index.html | 0
doc/assets/js/api-filter.js | 0
doc/assets/js/api-list.js | 0
doc/assets/js/api-search.js | 0
doc/assets/js/apidocs.js | 0
doc/assets/js/yui-prettify.js | 0
doc/assets/vendor/prettify/CHANGES.html | 0
doc/assets/vendor/prettify/COPYING | 0
doc/assets/vendor/prettify/README.html | 0
doc/assets/vendor/prettify/prettify-min.css | 0
doc/assets/vendor/prettify/prettify-min.js | 0
doc/classes/LGraph.html | 0
doc/classes/LGraphCanvas.html | 0
doc/classes/LGraphNode.html | 0
doc/classes/LiteGraph.html | 0
doc/classes/index.html | 0
doc/data.json | 0
doc/files/.._src_litegraph.js.html | 0
doc/files/index.html | 0
doc/index.html | 0
doc/modules/index.html | 0
external/Basica.otf | Bin
external/Criticized.otf | Bin
external/DS-Digital.otf | Bin
external/beat.otf | Bin
external/jquery-1.6.2.min.js | 0
index.html | 0
nodes_data/imgs/icon-sin.png | Bin
nodes_data/imgs/knob2_bg.png | Bin
nodes_data/imgs/knob2_fg.png | Bin
nodes_data/imgs/knob_bg.png | Bin
nodes_data/imgs/knob_fg.png | Bin
nodes_data/imgs/slider_fg.png | Bin
src/litegraph-editor.js | 0
src/litegraph.js | 183 +++++++++++---
src/nodes/base.js | 0
src/nodes/glfx.js | 0
src/nodes/gltextures.js | 48 +++-
src/nodes/image.js | 0
src/nodes/input.js | 0
src/nodes/interface.js | 0
src/nodes/logic.js | 0
src/nodes/math.js | 31 +++
src/nodes/others.js | 0
style.css | 0
utils/builder.py | 0
utils/deploy_files.txt | 0
utils/temp.js | 0
82 files changed, 490 insertions(+), 139 deletions(-)
mode change 100644 => 100755 LICENSE
mode change 100644 => 100755 README.md
mode change 100644 => 100755 build/litegraph.min.js
mode change 100644 => 100755 css/litegraph-editor.css
mode change 100644 => 100755 css/litegraph.css
mode change 100644 => 100755 demo/code.js
mode change 100644 => 100755 demo/code_old.js
mode change 100644 => 100755 demo/demo.js
mode change 100644 => 100755 demo/demodata/video.webm
mode change 100644 => 100755 demo/imgs/grid.png
mode change 100644 => 100755 demo/imgs/icon-edit.png
mode change 100644 => 100755 demo/imgs/icon-gear.png
mode change 100644 => 100755 demo/imgs/icon-load.png
mode change 100644 => 100755 demo/imgs/icon-maximize.png
mode change 100644 => 100755 demo/imgs/icon-play.png
mode change 100644 => 100755 demo/imgs/icon-playstep.png
mode change 100644 => 100755 demo/imgs/icon-record.png
mode change 100644 => 100755 demo/imgs/icon-save.png
mode change 100644 => 100755 demo/imgs/icon-stop.png
mode change 100644 => 100755 demo/imgs/load-progress-empty.png
mode change 100644 => 100755 demo/imgs/load-progress-full.png
mode change 100644 => 100755 demo/imgs/load-progress-grey.png
mode change 100644 => 100755 demo/imgs/play-icons-light-alpha.png
mode change 100644 => 100755 demo/imgs/play-icons-light.png
mode change 100644 => 100755 demo/imgs/play-icons.png
mode change 100644 => 100755 demo/index.html
mode change 100644 => 100755 demo/style.css
mode change 100644 => 100755 doc/api.js
mode change 100644 => 100755 doc/assets/css/external-small.png
mode change 100644 => 100755 doc/assets/css/logo.png
mode change 100644 => 100755 doc/assets/css/main.css
mode change 100644 => 100755 doc/assets/favicon.png
mode change 100644 => 100755 doc/assets/img/spinner.gif
mode change 100644 => 100755 doc/assets/index.html
mode change 100644 => 100755 doc/assets/js/api-filter.js
mode change 100644 => 100755 doc/assets/js/api-list.js
mode change 100644 => 100755 doc/assets/js/api-search.js
mode change 100644 => 100755 doc/assets/js/apidocs.js
mode change 100644 => 100755 doc/assets/js/yui-prettify.js
mode change 100644 => 100755 doc/assets/vendor/prettify/CHANGES.html
mode change 100644 => 100755 doc/assets/vendor/prettify/COPYING
mode change 100644 => 100755 doc/assets/vendor/prettify/README.html
mode change 100644 => 100755 doc/assets/vendor/prettify/prettify-min.css
mode change 100644 => 100755 doc/assets/vendor/prettify/prettify-min.js
mode change 100644 => 100755 doc/classes/LGraph.html
mode change 100644 => 100755 doc/classes/LGraphCanvas.html
mode change 100644 => 100755 doc/classes/LGraphNode.html
mode change 100644 => 100755 doc/classes/LiteGraph.html
mode change 100644 => 100755 doc/classes/index.html
mode change 100644 => 100755 doc/data.json
mode change 100644 => 100755 doc/files/.._src_litegraph.js.html
mode change 100644 => 100755 doc/files/index.html
mode change 100644 => 100755 doc/index.html
mode change 100644 => 100755 doc/modules/index.html
mode change 100644 => 100755 external/Basica.otf
mode change 100644 => 100755 external/Criticized.otf
mode change 100644 => 100755 external/DS-Digital.otf
mode change 100644 => 100755 external/beat.otf
mode change 100644 => 100755 external/jquery-1.6.2.min.js
mode change 100644 => 100755 index.html
mode change 100644 => 100755 nodes_data/imgs/icon-sin.png
mode change 100644 => 100755 nodes_data/imgs/knob2_bg.png
mode change 100644 => 100755 nodes_data/imgs/knob2_fg.png
mode change 100644 => 100755 nodes_data/imgs/knob_bg.png
mode change 100644 => 100755 nodes_data/imgs/knob_fg.png
mode change 100644 => 100755 nodes_data/imgs/slider_fg.png
mode change 100644 => 100755 src/litegraph-editor.js
mode change 100644 => 100755 src/litegraph.js
mode change 100644 => 100755 src/nodes/base.js
mode change 100644 => 100755 src/nodes/glfx.js
mode change 100644 => 100755 src/nodes/gltextures.js
mode change 100644 => 100755 src/nodes/image.js
mode change 100644 => 100755 src/nodes/input.js
mode change 100644 => 100755 src/nodes/interface.js
mode change 100644 => 100755 src/nodes/logic.js
mode change 100644 => 100755 src/nodes/math.js
mode change 100644 => 100755 src/nodes/others.js
mode change 100644 => 100755 style.css
mode change 100644 => 100755 utils/builder.py
mode change 100644 => 100755 utils/deploy_files.txt
mode change 100644 => 100755 utils/temp.js
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
diff --git a/build/litegraph.js b/build/litegraph.js
index 7d49fd8ab..17a58dea1 100644
--- a/build/litegraph.js
+++ b/build/litegraph.js
@@ -785,7 +785,7 @@ LGraph.prototype.getNodeOnPos = function(x,y, nodes_list)
for (var i = nodes_list.length - 1; i >= 0; i--)
{
var n = nodes_list[i];
- if(n.isPointInsideNode(x,y))
+ if(n.isPointInsideNode( x, y, 2 ))
return n;
}
return null;
@@ -1126,7 +1126,15 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
// Node CLASS *******
// *************************************************************
-/* flags:
+/*
+ title: string
+ pos: [x,y]
+ size: [x,y]
+
+ input|output: every connection
+ + { name:string, type:string, pos: [x,y]=Optional, direction: "input"|"output", links: Array });
+
+ flags:
+ skip_title_render
+ clip_area
+ unsafe_execution: not allowed for safe execution
@@ -1352,7 +1360,7 @@ LGraphNode.prototype.setOutputData = function(slot,data)
* retrieves the input data (data traveling through the connection) from one slot
* @method getInputData
* @param {number} slot
-* @return {*} data
+* @return {*} data or if it is not connected returns undefined
*/
LGraphNode.prototype.getInputData = function(slot)
{
@@ -1380,11 +1388,12 @@ LGraphNode.prototype.isInputConnected = function(slot)
* tells you info about an input connection (which node, type, etc)
* @method getInputInfo
* @param {number} slot
-* @return {Object}
+* @return {Object} object or null
*/
LGraphNode.prototype.getInputInfo = function(slot)
{
- if(!this.inputs) return null;
+ if(!this.inputs)
+ return null;
if(slot < this.inputs.length)
return this.inputs[slot];
return null;
@@ -1395,11 +1404,12 @@ LGraphNode.prototype.getInputInfo = function(slot)
* tells you info about an output connection (which node, type, etc)
* @method getOutputInfo
* @param {number} slot
-* @return {Object}
+* @return {Object} object or null
*/
LGraphNode.prototype.getOutputInfo = function(slot)
{
- if(!this.outputs) return null;
+ if(!this.outputs)
+ return null;
if(slot < this.outputs.length)
return this.outputs[slot];
return null;
@@ -1414,7 +1424,8 @@ LGraphNode.prototype.getOutputInfo = function(slot)
*/
LGraphNode.prototype.isOutputConnected = function(slot)
{
- if(!this.outputs) return null;
+ if(!this.outputs)
+ return null;
return (slot < this.outputs.length && this.outputs[slot].links && this.outputs[slot].links.length);
}
@@ -1522,7 +1533,8 @@ LGraphNode.prototype.addInput = function(name,type,extra_info)
for(var i in extra_info)
o[i] = extra_info[i];
- if(!this.inputs) this.inputs = [];
+ if(!this.inputs)
+ this.inputs = [];
this.inputs.push(o);
this.size = this.computeSize();
if(this.onInputAdded)
@@ -1591,11 +1603,44 @@ LGraphNode.prototype.computeSize = function(minHeight)
{
var rows = Math.max( this.inputs ? this.inputs.length : 1, this.outputs ? this.outputs.length : 1);
var size = new Float32Array([0,0]);
+ rows = Math.max(rows, 1);
size[1] = rows * 14 + 6;
- if(!this.inputs || this.inputs.length == 0 || !this.outputs || this.outputs.length == 0)
- size[0] = LiteGraph.NODE_WIDTH * 0.5;
- else
- size[0] = LiteGraph.NODE_WIDTH;
+
+ var font_size = 14;
+ var title_width = compute_text_size( this.title );
+ var input_width = 0;
+ var output_width = 0;
+
+ if(this.inputs)
+ for(var i = 0, l = this.inputs.length; i < l; ++i)
+ {
+ var input = this.inputs[i];
+ var text = input.label || input.name || "";
+ var text_width = compute_text_size( text );
+ if(input_width < text_width)
+ input_width = text_width;
+ }
+
+ if(this.outputs)
+ for(var i = 0, l = this.outputs.length; i < l; ++i)
+ {
+ var output = this.outputs[i];
+ var text = output.label || output.name || "";
+ var text_width = compute_text_size( text );
+ if(output_width < text_width)
+ output_width = text_width;
+ }
+
+ size[0] = Math.max( input_width + output_width + 10, title_width );
+ size[0] = Math.max( size[0], LiteGraph.NODE_WIDTH );
+
+ function compute_text_size( text )
+ {
+ if(!text)
+ return 0;
+ return font_size * text.length * 0.6;
+ }
+
return size;
}
@@ -1616,21 +1661,54 @@ LGraphNode.prototype.getBounding = function()
* @param {number} y
* @return {boolean}
*/
-LGraphNode.prototype.isPointInsideNode = function(x,y)
+LGraphNode.prototype.isPointInsideNode = function(x,y, margin)
{
+ margin = margin || 0;
+
var margin_top = this.graph && this.graph.isLive() ? 0 : 20;
if(this.flags.collapsed)
{
//if ( distance([x,y], [this.pos[0] + this.size[0]*0.5, this.pos[1] + this.size[1]*0.5]) < LiteGraph.NODE_COLLAPSED_RADIUS)
- if( isInsideRectangle(x,y, this.pos[0], this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_COLLAPSED_WIDTH, LiteGraph.NODE_TITLE_HEIGHT) )
+ if( isInsideRectangle( x, y, this.pos[0] - margin, this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT - margin, LiteGraph.NODE_COLLAPSED_WIDTH + 2 * margin, LiteGraph.NODE_TITLE_HEIGHT + 2 * margin ) )
return true;
}
- else if (this.pos[0] - 4 < x && (this.pos[0] + this.size[0] + 4) > x
- && (this.pos[1] - margin_top) < y && (this.pos[1] + this.size[1]) > y)
+ else if ( (this.pos[0] - 4 - margin) < x && (this.pos[0] + this.size[0] + 4 + margin) > x
+ && (this.pos[1] - margin_top - margin) < y && (this.pos[1] + this.size[1] + margin) > y)
return true;
return false;
}
+/**
+* checks if a point is inside a node slot, and returns info about which slot
+* @method getSlotInPosition
+* @param {number} x
+* @param {number} y
+* @return {Object} if found the object contains { input|output: slot object, slot: number, link_pos: [x,y] }
+*/
+LGraphNode.prototype.getSlotInPosition = function( x, y )
+{
+ //search for inputs
+ if(this.inputs)
+ for(var i = 0, l = this.inputs.length; i < l; ++i)
+ {
+ var input = this.inputs[i];
+ var link_pos = this.getConnectionPos( true,i );
+ if( isInsideRectangle(x, y, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
+ return { input: input, slot: i, link_pos: link_pos, locked: input.locked };
+ }
+
+ if(this.outputs)
+ for(var i = 0, l = this.outputs.length; i < l; ++i)
+ {
+ var output = this.outputs[i];
+ var link_pos = this.getConnectionPos(false,i);
+ if( isInsideRectangle(x, y, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
+ return { output: output, slot: i, link_pos: link_pos, locked: output.locked };
+ }
+
+ return null;
+}
+
/**
* returns the input slot with a given name (used for dynamic slots), -1 if not found
* @method findInputSlot
@@ -1838,28 +1916,33 @@ LGraphNode.prototype.disconnectInput = function(slot)
}
var input = this.inputs[slot];
- if(!input) return false;
+ if(!input)
+ return false;
var link_id = this.inputs[slot].link;
this.inputs[slot].link = null;
//remove other side
var link_info = this.graph.links[ link_id ];
- var node = this.graph.getNodeById( link_info.origin_id );
- if(!node) return false;
-
- var output = node.outputs[ link_info.origin_slot ];
- if(!output || !output.links || output.links.length == 0)
- return false;
-
- //check outputs
- for(var i = 0, l = output.links.length; i < l; i++)
+ if( link_info )
{
- var link_id = output.links[i];
- var link_info = this.graph.links[ link_id ];
- if( link_info.target_id == this.id )
+ var node = this.graph.getNodeById( link_info.origin_id );
+ if(!node)
+ return false;
+
+ var output = node.outputs[ link_info.origin_slot ];
+ if(!output || !output.links || output.links.length == 0)
+ return false;
+
+ //check outputs
+ for(var i = 0, l = output.links.length; i < l; i++)
{
- output.links.splice(i,1);
- break;
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+ if( link_info.target_id == this.id )
+ {
+ output.links.splice(i,1);
+ break;
+ }
}
}
@@ -1875,7 +1958,7 @@ LGraphNode.prototype.disconnectInput = function(slot)
* @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot)
* @return {[x,y]} the position
**/
-LGraphNode.prototype.getConnectionPos = function(is_input,slot_number)
+LGraphNode.prototype.getConnectionPos = function(is_input, slot_number)
{
if(this.flags.collapsed)
{
@@ -2512,7 +2595,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
- var n = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes);
+ var n = this.graph.getNodeOnPos( e.canvasX, e.canvasY, this.visible_nodes );
var skip_dragging = false;
if(e.which == 1) //left button mouse
@@ -4387,16 +4470,42 @@ LGraphCanvas.prototype.getNodeMenuOptions = function(node)
return options;
}
-LGraphCanvas.prototype.processContextualMenu = function(node,event)
+LGraphCanvas.prototype.processContextualMenu = function(node, event)
{
var that = this;
var win = this.getCanvasWindow();
- var menu = LiteGraph.createContextualMenu(node ? this.getNodeMenuOptions(node) : this.getCanvasMenuOptions(), {event: event, callback: inner_option_clicked}, win);
+ var menu_info = null;
+
+ //check if mouse is in input
+ var slot = null;
+ if(node)
+ slot = node.getSlotInPosition( event.canvasX, event.canvasY );
+
+ if(slot)
+ menu_info = slot.locked ? [ "Cannot remove" ] : { "Remove Slot": slot };
+ else
+ menu_info = node ? this.getNodeMenuOptions(node) : this.getCanvasMenuOptions();
+
+ //show menu
+ if(!menu_info)
+ return;
+
+ var menu = LiteGraph.createContextualMenu( menu_info, {event: event, callback: inner_option_clicked}, win);
function inner_option_clicked(v,e)
{
- if(!v) return;
+ if(!v)
+ return;
+
+ if(v == slot)
+ {
+ if(v.input)
+ node.removeInput( slot.slot );
+ else if(v.output)
+ node.removeOutput( slot.slot );
+ return;
+ }
if(v.callback)
return v.callback(node, e, menu, that, event );
@@ -6098,6 +6207,37 @@ MathFrac.prototype.onExecute = function()
LiteGraph.registerNodeType("math/frac",MathFrac);
+//Math Floor
+function MathSmoothStep()
+{
+ this.addInput("in","number");
+ this.addOutput("out","number");
+ this.size = [60,20];
+ this.properties = { A: 0, B: 1 };
+}
+
+MathSmoothStep.title = "Smoothstep";
+MathSmoothStep.desc = "Smoothstep";
+
+MathSmoothStep.prototype.onExecute = function()
+{
+ var v = this.getInputData(0);
+ if(v === undefined)
+ return;
+
+ var edge0 = this.properties.A;
+ var edge1 = this.properties.B;
+
+ // Scale, bias and saturate x to 0..1 range
+ v = Math.clamp((v - edge0)/(edge1 - edge0), 0.0, 1.0);
+ // Evaluate polynomial
+ v = v*v*(3 - 2*v);
+
+ this.setOutputData(0, v );
+}
+
+LiteGraph.registerNodeType("math/smoothstep", MathSmoothStep );
+
//Math scale
function MathScale()
{
@@ -7650,6 +7790,9 @@ if(typeof(LiteGraph) != "undefined")
{
var tex = this.getInputData(0);
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
if(this.properties.precision === LGraphTexture.PASS_THROUGH)
{
this.setOutputData(0, tex);
@@ -7790,12 +7933,15 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureShader.title = "Shader";
LGraphTextureShader.desc = "Texture shader";
LGraphTextureShader.widgets_info = {
- "code": { widget:"code" },
+ "code": { type:"code" },
"precision": { widget:"combo", values: LGraphTexture.MODE_VALUES }
};
LGraphTextureShader.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
//replug
if(this._shader_code != this.properties.code)
{
@@ -7991,6 +8137,9 @@ if(typeof(LiteGraph) != "undefined")
if(!tex && !this._temp_texture)
return;
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
//copy the texture
if(tex)
{
@@ -8049,7 +8198,11 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureAverage.prototype.onExecute = function()
{
var tex = this.getInputData(0);
- if(!tex) return;
+ if(!tex)
+ return;
+
+ if(!this.isOutputConnected(0))
+ return; //saves work
if(!LGraphTextureAverage._shader)
{
@@ -8109,7 +8262,8 @@ if(typeof(LiteGraph) != "undefined")
LGraphImageToTexture.prototype.onExecute = function()
{
var img = this.getInputData(0);
- if(!img) return;
+ if(!img)
+ return;
var width = img.videoWidth || img.width;
var height = img.videoHeight || img.height;
@@ -8165,6 +8319,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureLUT.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
@@ -8496,6 +8653,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureMix.prototype.onExecute = function()
{
var texA = this.getInputData(0);
+
+ if(!this.isOutputConnected(0))
+ return; //saves work
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
{
@@ -8545,7 +8705,7 @@ if(typeof(LiteGraph) != "undefined")
this.addInput("Tex.","Texture");
this.addOutput("Edges","Texture");
- this.properties = { invert: true, precision: LGraphTexture.DEFAULT };
+ this.properties = { invert: true, factor: 1, precision: LGraphTexture.DEFAULT };
if(!LGraphTextureEdges._shader)
LGraphTextureEdges._shader = new GL.Shader( Shader.SCREEN_VERTEX_SHADER, LGraphTextureEdges.pixel_shader );
@@ -8560,6 +8720,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureEdges.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
@@ -8578,10 +8741,11 @@ if(typeof(LiteGraph) != "undefined")
var mesh = Mesh.getScreenQuad();
var shader = LGraphTextureEdges._shader;
var invert = this.properties.invert;
+ var factor = this.properties.factor;
this._tex.drawTo( function() {
tex.bind(0);
- shader.uniforms({u_texture:0, u_isize:[1/tex.width,1/tex.height], u_invert: invert ? 1 : 0}).draw(mesh);
+ shader.uniforms({u_texture:0, u_isize:[1/tex.width,1/tex.height], u_factor: factor, u_invert: invert ? 1 : 0}).draw(mesh);
});
this.setOutputData(0, this._tex);
@@ -8593,6 +8757,7 @@ if(typeof(LiteGraph) != "undefined")
uniform sampler2D u_texture;\n\
uniform vec2 u_isize;\n\
uniform int u_invert;\n\
+ uniform float u_factor;\n\
\n\
void main() {\n\
vec4 center = texture2D(u_texture, v_coord);\n\
@@ -8601,6 +8766,7 @@ if(typeof(LiteGraph) != "undefined")
vec4 left = texture2D(u_texture, v_coord + u_isize * vec2(1.0,0.0) );\n\
vec4 right = texture2D(u_texture, v_coord + u_isize * vec2(-1.0,0.0) );\n\
vec4 diff = abs(center - up) + abs(center - down) + abs(center - left) + abs(center - right);\n\
+ diff *= u_factor;\n\
if(u_invert == 1)\n\
diff.xyz = vec3(1.0) - diff.xyz;\n\
gl_FragColor = vec4( diff.xyz, center.a );\n\
@@ -8627,6 +8793,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureDepthRange.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
var tex = this.getInputData(0);
if(!tex) return;
@@ -8718,7 +8887,11 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureBlur.prototype.onExecute = function()
{
var tex = this.getInputData(0);
- if(!tex) return;
+ if(!tex)
+ return;
+
+ if(!this.isOutputConnected(0))
+ return; //saves work
var temp = this._temp_texture;
@@ -8905,7 +9078,8 @@ if(typeof(LiteGraph) != "undefined")
if(this._webcam_stream == null && !this._waiting_confirmation)
this.openStream();
- if(!this._video || !this._video.videoWidth) return;
+ if(!this._video || !this._video.videoWidth)
+ return;
var width = this._video.videoWidth;
var height = this._video.videoHeight;
diff --git a/build/litegraph.min.js b/build/litegraph.min.js
old mode 100644
new mode 100755
index 890311d83..a5fc8e4fe
--- a/build/litegraph.min.js
+++ b/build/litegraph.min.js
@@ -16,7 +16,7 @@ LGraph.prototype.sendEventToAllNodes=function(a,b){var c=this._nodes_in_order?th
LGraph.prototype.add=function(a,b){if(a&&(-1==a.id||null==this._nodes_by_id[a.id])){if(this._nodes.length>=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(null==a.id||-1==a.id)a.id=this.last_node_id++;a.graph=this;this._nodes.push(a);this._nodes_by_id[a.id]=a;if(a.onAdded)a.onAdded();this.config.align_to_grid&&a.alignToGrid();b||this.updateExecutionOrder();if(this.onNodeAdded)this.onNodeAdded(a);this.setDirtyCanvas(!0);this.change();return a}};
LGraph.prototype.remove=function(a){if(null!=this._nodes_by_id[a.id]&&!a.ignore_remove){if(a.inputs)for(var b=0;ba&&this.pos[1]-cb)return!0;return!1};
+LGraphNode.prototype.addConnection=function(a,b,c,d){this.connections.push({name:a,type:b,pos:c,direction:d,links:null})};
+LGraphNode.prototype.computeSize=function(a){function b(a){return a?d*a.length*0.6:0}var c=Math.max(this.inputs?this.inputs.length:1,this.outputs?this.outputs.length:1);a=new Float32Array([0,0]);c=Math.max(c,1);a[1]=14*c+6;var d=14,c=b(this.title),e=0,f=0;if(this.inputs)for(var g=0,h=this.inputs.length;ga&&this.pos[1]-d-cb)return!0;return!1};
+LGraphNode.prototype.getSlotInPosition=function(a,b){if(this.inputs)for(var c=0,d=this.inputs.length;c=this.outputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(b==this)return!1;if(c.constructor===String){if(c=b.findInputSlot(c),-1==c)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+c),!1}else if(!b.inputs||c>=b.inputs.length)return LiteGraph.debug&&
console.log("Connect: Error, slot number not found"),!1;-1!=c&&null!=b.inputs[c].link&&b.disconnectInput(c);var d=this.outputs[a];-1==c?(null==d.links&&(d.links=[]),d.links.push({id:b.id,slot:-1})):d.type&&b.inputs[c].type&&d.type.toLowerCase()!=b.inputs[c].type.toLowerCase()||(a={id:this.graph.last_link_id++,origin_id:this.id,origin_slot:a,target_id:b.id,target_slot:c},this.graph.links[a.id]=a,null==d.links&&(d.links=[]),d.links.push(a.id),b.inputs[c].link=a.id,this.setDirtyCanvas(!1,!0),this.graph.onConnectionChange());
return!0};
LGraphNode.prototype.disconnectOutput=function(a,b){if(a.constructor===String){if(a=this.findOutputSlot(a),-1==a)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+a),!1}else if(!this.outputs||a>=this.outputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;var c=this.outputs[a];if(!c.links||0==c.links.length)return!1;if(b)for(var d=0,e=c.links.length;d=this.inputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(!this.inputs[a])return!1;var b=this.inputs[a].link;this.inputs[a].link=null;b=this.graph.links[b];a=this.graph.getNodeById(b.origin_id);if(!a)return!1;a=a.outputs[b.origin_slot];if(!a||!a.links||
-0==a.links.length)return!1;for(var c=0,d=a.links.length;c=this.inputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(!this.inputs[a])return!1;var b=this.inputs[a].link;this.inputs[a].link=null;if(b=this.graph.links[b]){a=this.graph.getNodeById(b.origin_id);if(!a)return!1;a=a.outputs[b.origin_slot];if(!a||
+!a.links||0==a.links.length)return!1;for(var c=0,d=a.links.length;cb&&this.inputs[b].pos?[this.pos[0]+this.inputs[b].pos[0],this.pos[1]+this.inputs[b].pos[1]]:!a&&this.outputs.length>b&&this.outputs[b].pos?[this.pos[0]+this.outputs[b].pos[0],this.pos[1]+this.outputs[b].pos[1]]:
a?[this.pos[0],this.pos[1]+10+b*LiteGraph.NODE_SLOT_HEIGHT]:[this.pos[0]+this.size[0]+1,this.pos[1]+10+b*LiteGraph.NODE_SLOT_HEIGHT]};LGraphNode.prototype.alignToGrid=function(){this.pos[0]=LiteGraph.CANVAS_GRID_SIZE*Math.round(this.pos[0]/LiteGraph.CANVAS_GRID_SIZE);this.pos[1]=LiteGraph.CANVAS_GRID_SIZE*Math.round(this.pos[1]/LiteGraph.CANVAS_GRID_SIZE)};
LGraphNode.prototype.trace=function(a){this.console||(this.console=[]);this.console.push(a);this.console.length>LGraphNode.MAX_CONSOLE&&this.console.shift();this.graph.onNodeTrace(this,a)};LGraphNode.prototype.setDirtyCanvas=function(a,b){this.graph&&this.graph.sendActionToCanvas("setDirty",[a,b])};LGraphNode.prototype.loadImage=function(a){var b=new Image;b.src=LiteGraph.node_images_path+a;b.ready=!1;var c=this;b.onload=function(){this.ready=!0;c.setDirtyCanvas(!0)};return b};
@@ -130,7 +132,7 @@ LGraphCanvas.node_colors={red:{color:"#FAA",bgcolor:"#A44"},green:{color:"#AFA",
LGraphCanvas.prototype.getCanvasMenuOptions=function(){var a=null;this.getMenuOptions?a=this.getMenuOptions():(a=[{content:"Add Node",is_menu:!0,callback:LGraphCanvas.onMenuAdd}],this._graph_stack&&0a&&db?!0:!1}function growBounding(a,b,c){ba[2]&&(a[2]=b);ca[3]&&(a[3]=c)}
function isInsideBounding(a,b){return a[0]b[1][0]||a[1]>b[1][1]?!1:!0}function overlapBounding(a,b){return a[0]>b[2]||a[1]>b[3]||a[2]f;f+=2)d="0123456789ABCDEF".indexOf(a.charAt(f)),e="0123456789ABCDEF".indexOf(a.charAt(f+1)),b[c]=16*d+e,c++;return b}
@@ -177,25 +179,26 @@ a.buttons[d].pressed;break;case 3:c.buttons.y=a.buttons[d].pressed;break;case 4:
case 13:a.buttons[d].pressed&&(c.hat+="down");break;case 14:a.buttons[d].pressed&&(c.hat+="left");break;case 15:a.buttons[d].pressed&&(c.hat+="right");break;case 16:c.buttons.home=a.buttons[d].pressed}a.xbox=c;return a}};a.prototype.onDrawBackground=function(a){};a.prototype.onGetOutputs=function(){return[["left_x_axis","number"],["left_y_axis","number"],["right_x_axis","number"],["right_y_axis","number"],["trigger","number"],["a_button","number"],["b_button","number"],["x_button","number"],["y_button",
"number"],["lb_button","number"],["rb_button","number"],["ls_button","number"],["rs_button","number"],["start","number"],["back","number"]]};LiteGraph.registerNodeType("input/gamepad",a)})();
(function(){function a(){this.addOutput("value","number");this.properties={min:0,max:1};this.size=[60,20]}function b(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20];this.properties={min:0,max:1}}function c(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function d(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function e(){this.addInput("in","number");this.addOutput("out","number");this.size=[60,20]}function f(){this.addInput("in",
-"number",{label:""});this.addOutput("out","number",{label:""});this.size=[60,20];this.properties={factor:1}}function g(){this.addInput("A","number");this.addInput("B","number");this.addOutput("=","number");this.properties={A:1,B:1,OP:"+"}}function h(){this.addInput("A","number");this.addInput("B","number");this.addOutput("A==B","boolean");this.addOutput("A!=B","boolean");this.properties={A:0,B:0}}function k(){this.addInput("A","number");this.addInput("B","number");this.addOutput("out","boolean");
-this.properties={A:0,B:1,OP:">"};this.size=[60,40]}function n(){this.addInput("inc","number");this.addOutput("total","number");this.properties={increment:0,value:0}}function p(){this.addInput("v","number");this.addOutput("sin","number");this.properties={amplitude:1,offset:0};this.bgImageUrl="nodes/imgs/icon-sin.png"}a.title="Rand";a.desc="Random number";a.prototype.onExecute=function(){if(this.inputs)for(var a=0;aB":value=a>b;break;case "A=B":value=a>=b}this.setOutputData(c,value)}}};h.prototype.onGetOutputs=function(){return[["A==B","boolean"],["A!=B","boolean"],["A>B","boolean"],["A=B","boolean"],["A<=B","boolean"]]};LiteGraph.registerNodeType("math/compare",h);k["@OP"]={type:"enum",title:"operation",values:"> < == != <= >=".split(" ")};
-k.title="Condition";k.desc="evaluates condition between A and B";k.prototype.onExecute=function(){var a=this.getInputData(0);void 0===a?a=this.properties.A:this.properties.A=a;var b=this.getInputData(1);void 0===b?b=this.properties.B:this.properties.B=b;var c=!0;switch(this.properties.OP){case ">":c=a>b;break;case "<":c=a=":c=a>=b}this.setOutputData(0,c)};LiteGraph.registerNodeType("math/condition",k);n.title="Accumulate";
-n.desc="Increments a value every time";n.prototype.onExecute=function(){var a=this.getInputData(0);this.properties.value=null!==a?this.properties.value+a:this.properties.value+this.properties.increment;this.setOutputData(0,this.properties.value)};LiteGraph.registerNodeType("math/accumulate",n);p.title="Trigonometry";p.desc="Sin Cos Tan";p.filter="shader";p.prototype.onExecute=function(){var a=this.getInputData(0),b=this.properties.amplitude,c=this.findInputSlot("amplitude");-1!=c&&(b=this.getInputData(c));
-var d=this.properties.offset,c=this.findInputSlot("offset");-1!=c&&(d=this.getInputData(c));for(var c=0,e=this.outputs.length;cXYZ",l.desc="vector 3 to components",l.prototype.onExecute=function(){var a=this.getInputData(0);null!=a&&(this.setOutputData(0,a[0]),this.setOutputData(1,a[1]),this.setOutputData(2,a[2]))},LiteGraph.registerNodeType("math3d/vec3-to-xyz",l),l=function(){this.addInputs([["x","number"],["y","number"],["z","number"]]);this.addOutput("vec3","vec3");this.properties={x:0,y:0,z:0}},l.title="XYZ->Vec3",l.desc="components to vector3",l.prototype.onExecute=
-function(){var a=this.getInputData(0);null==a&&(a=this.properties.x);var b=this.getInputData(1);null==b&&(b=this.properties.y);var c=this.getInputData(2);null==c&&(c=this.properties.z);this.setOutputData(0,vec3.fromValues(a,b,c))},LiteGraph.registerNodeType("math3d/xyz-to-vec3",l),l=function(){this.addInputs([["degrees","number"],["axis","vec3"]]);this.addOutput("quat","quat");this.properties={angle:90,axis:vec3.fromValues(0,1,0)}},l.title="Rotation",l.desc="quaternion rotation",l.prototype.onExecute=
-function(){var a=this.getInputData(0);null==a&&(a=this.properties.angle);var b=this.getInputData(1);null==b&&(b=this.properties.axis);a=quat.setAxisAngle(quat.create(),b,0.0174532925*a);this.setOutputData(0,a)},LiteGraph.registerNodeType("math3d/rotation",l),l=function(){this.addInputs([["vec3","vec3"],["quat","quat"]]);this.addOutput("result","vec3");this.properties={vec:[0,0,1]}},l.title="Rot. Vec3",l.desc="rotate a point",l.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=
-this.properties.vec);var b=this.getInputData(1);null==b?this.setOutputData(a):this.setOutputData(0,vec3.transformQuat(vec3.create(),a,b))},LiteGraph.registerNodeType("math3d/rotate_vec3",l),l=function(){this.addInputs([["A","quat"],["B","quat"]]);this.addOutput("A*B","quat")},l.title="Mult. Quat",l.desc="rotate quaternion",l.prototype.onExecute=function(){var a=this.getInputData(0);if(null!=a){var b=this.getInputData(1);null!=b&&(a=quat.multiply(quat.create(),a,b),this.setOutputData(0,a))}},LiteGraph.registerNodeType("math3d/mult-quat",
-l))})();function Selector(){this.addInput("sel","boolean");this.addOutput("value","number");this.properties={A:0,B:1};this.size=[60,20]}Selector.title="Selector";Selector.desc="outputs A if selector is true, B if selector is false";
-Selector.prototype.onExecute=function(){var a=this.getInputData(0);if(void 0!==a){for(var b=1;b"};this.size=[60,40]}function p(){this.addInput("inc","number");this.addOutput("total","number");this.properties={increment:0,value:0}}function q(){this.addInput("v","number");this.addOutput("sin","number");this.properties={amplitude:1,offset:0};this.bgImageUrl="nodes/imgs/icon-sin.png"}a.title="Rand";a.desc="Random number";a.prototype.onExecute=function(){if(this.inputs)for(var a=
+0;aB":value=a>b;
+break;case "A=B":value=a>=b}this.setOutputData(c,value)}}};k.prototype.onGetOutputs=function(){return[["A==B","boolean"],["A!=B","boolean"],["A>B","boolean"],["A=B","boolean"],["A<=B","boolean"]]};LiteGraph.registerNodeType("math/compare",k);n["@OP"]={type:"enum",title:"operation",values:"> < == != <= >=".split(" ")};n.title="Condition";n.desc="evaluates condition between A and B";n.prototype.onExecute=function(){var a=this.getInputData(0);
+void 0===a?a=this.properties.A:this.properties.A=a;var b=this.getInputData(1);void 0===b?b=this.properties.B:this.properties.B=b;var c=!0;switch(this.properties.OP){case ">":c=a>b;break;case "<":c=a=":c=a>=b}this.setOutputData(0,c)};LiteGraph.registerNodeType("math/condition",n);p.title="Accumulate";p.desc="Increments a value every time";p.prototype.onExecute=function(){var a=this.getInputData(0);this.properties.value=
+null!==a?this.properties.value+a:this.properties.value+this.properties.increment;this.setOutputData(0,this.properties.value)};LiteGraph.registerNodeType("math/accumulate",p);q.title="Trigonometry";q.desc="Sin Cos Tan";q.filter="shader";q.prototype.onExecute=function(){var a=this.getInputData(0),b=this.properties.amplitude,c=this.findInputSlot("amplitude");-1!=c&&(b=this.getInputData(c));var d=this.properties.offset,c=this.findInputSlot("offset");-1!=c&&(d=this.getInputData(c));for(var c=0,e=this.outputs.length;c<
+e;++c){switch(this.outputs[c].name){case "sin":value=Math.sin(a);break;case "cos":value=Math.cos(a);break;case "tan":value=Math.tan(a);break;case "asin":value=Math.asin(a);break;case "acos":value=Math.acos(a);break;case "atan":value=Math.atan(a)}this.setOutputData(c,b*value+d)}};q.prototype.onGetInputs=function(){return[["v","number"],["amplitude","number"],["offset","number"]]};q.prototype.onGetOutputs=function(){return[["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos",
+"number"],["atan","number"]]};LiteGraph.registerNodeType("math/trigonometry",q);if(window.math){var l=function(){this.addInputs("x","number");this.addInputs("y","number");this.addOutputs("","number");this.properties={x:1,y:1,formula:"x+y"}};l.title="Formula";l.desc="Compute safe formula";l.prototype.onExecute=function(){var a=this.getInputData(0),b=this.getInputData(1);null!=a?this.properties.x=a:a=this.properties.x;null!=b?this.properties.y=b:b=this.properties.y;a=math.eval(this.properties.formula,
+{x:a,y:b,T:this.graph.globaltime});this.setOutputData(0,a)};l.prototype.onDrawBackground=function(){this.outputs[0].label=this.properties.formula};l.prototype.onGetOutputs=function(){return[["A-B","number"],["A*B","number"],["A/B","number"]]};LiteGraph.registerNodeType("math/formula",l)}window.glMatrix&&(l=function(){this.addInput("vec3","vec3");this.addOutput("x","number");this.addOutput("y","number");this.addOutput("z","number")},l.title="Vec3->XYZ",l.desc="vector 3 to components",l.prototype.onExecute=
+function(){var a=this.getInputData(0);null!=a&&(this.setOutputData(0,a[0]),this.setOutputData(1,a[1]),this.setOutputData(2,a[2]))},LiteGraph.registerNodeType("math3d/vec3-to-xyz",l),l=function(){this.addInputs([["x","number"],["y","number"],["z","number"]]);this.addOutput("vec3","vec3");this.properties={x:0,y:0,z:0}},l.title="XYZ->Vec3",l.desc="components to vector3",l.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.x);var b=this.getInputData(1);null==b&&(b=this.properties.y);
+var c=this.getInputData(2);null==c&&(c=this.properties.z);this.setOutputData(0,vec3.fromValues(a,b,c))},LiteGraph.registerNodeType("math3d/xyz-to-vec3",l),l=function(){this.addInputs([["degrees","number"],["axis","vec3"]]);this.addOutput("quat","quat");this.properties={angle:90,axis:vec3.fromValues(0,1,0)}},l.title="Rotation",l.desc="quaternion rotation",l.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.angle);var b=this.getInputData(1);null==b&&(b=this.properties.axis);
+a=quat.setAxisAngle(quat.create(),b,0.0174532925*a);this.setOutputData(0,a)},LiteGraph.registerNodeType("math3d/rotation",l),l=function(){this.addInputs([["vec3","vec3"],["quat","quat"]]);this.addOutput("result","vec3");this.properties={vec:[0,0,1]}},l.title="Rot. Vec3",l.desc="rotate a point",l.prototype.onExecute=function(){var a=this.getInputData(0);null==a&&(a=this.properties.vec);var b=this.getInputData(1);null==b?this.setOutputData(a):this.setOutputData(0,vec3.transformQuat(vec3.create(),a,
+b))},LiteGraph.registerNodeType("math3d/rotate_vec3",l),l=function(){this.addInputs([["A","quat"],["B","quat"]]);this.addOutput("A*B","quat")},l.title="Mult. Quat",l.desc="rotate quaternion",l.prototype.onExecute=function(){var a=this.getInputData(0);if(null!=a){var b=this.getInputData(1);null!=b&&(a=quat.multiply(quat.create(),a,b),this.setOutputData(0,a))}},LiteGraph.registerNodeType("math3d/mult-quat",l))})();
+function Selector(){this.addInput("sel","boolean");this.addOutput("value","number");this.properties={A:0,B:1};this.size=[60,20]}Selector.title="Selector";Selector.desc="outputs A if selector is true, B if selector is false";Selector.prototype.onExecute=function(){var a=this.getInputData(0);if(void 0!==a){for(var b=1;bpixelcode must be vec3
\t\t\tuvcode must be vec2, is optional
\t\t\tuv: tex. coords
color: texture
colorB: textureB
time: scene time
value: input value
";this.properties={value:1,uvcode:"",pixelcode:"color + colorB * value",precision:LGraphTexture.DEFAULT}};LGraphTextureOperation.widgets_info={uvcode:{widget:"textarea",
height:100},pixelcode:{widget:"textarea",height:100},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureOperation.title="Operation";LGraphTextureOperation.desc="Texture shader operation";LGraphTextureOperation.prototype.getExtraMenuOptions=function(a){var b=this;return[{content:b.properties.show?"Hide Texture":"Show Texture",callback:function(){b.properties.show=!b.properties.show}}]};LGraphTextureOperation.prototype.onDrawBackground=function(a){this.flags.collapsed||20>=this.size[1]||
-!this.properties.show||!this._tex||this._tex.gl!=a||(a.save(),a.drawImage(this._tex,0,0,this.size[0],this.size[1]),a.restore())};LGraphTextureOperation.prototype.onExecute=function(){var a=this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else{var b=this.getInputData(1);if(this.properties.uvcode||this.properties.pixelcode){var c=512,d=512;a?(c=a.width,d=a.height):b&&(c=b.width,d=b.height);this._tex=a||this._tex?LGraphTexture.getTargetTexture(a||
+!this.properties.show||!this._tex||this._tex.gl!=a||(a.save(),a.drawImage(this._tex,0,0,this.size[0],this.size[1]),a.restore())};LGraphTextureOperation.prototype.onExecute=function(){var a=this.getInputData(0);if(this.isOutputConnected(0))if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else{var b=this.getInputData(1);if(this.properties.uvcode||this.properties.pixelcode){var c=512,d=512;a?(c=a.width,d=a.height):b&&(c=b.width,d=b.height);this._tex=a||this._tex?LGraphTexture.getTargetTexture(a||
this._tex,this._tex,this.properties.precision):new GL.Texture(c,d,{type:this.precision===LGraphTexture.LOW?gl.UNSIGNED_BYTE:gl.HIGH_PRECISION_FORMAT,format:gl.RGBA,filter:gl.LINEAR});var e="";this.properties.uvcode&&(e="uv = "+this.properties.uvcode,-1!=this.properties.uvcode.indexOf(";")&&(e=this.properties.uvcode));var f="";this.properties.pixelcode&&(f="result = "+this.properties.pixelcode,-1!=this.properties.pixelcode.indexOf(";")&&(f=this.properties.pixelcode));var g=this._shader;if(!g||this._shader_code!=
e+"|"+f){try{this._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureOperation.pixel_shader,{UV_CODE:e,PIXEL_CODE:f}),this.boxcolor="#00FF00"}catch(h){console.log("Error compiling shader: ",h);this.boxcolor="#FF0000";return}this._shader_code=e+"|"+f;g=this._shader}if(g){this.boxcolor="green";var k=this.getInputData(2);null!=k?this.properties.value=k:k=parseFloat(this.properties.value);var n=this.graph.getTime();this._tex.drawTo(function(){gl.disable(gl.DEPTH_TEST);gl.disable(gl.CULL_FACE);
gl.disable(gl.BLEND);a&&a.bind(0);b&&b.bind(1);var e=Mesh.getScreenQuad();g.uniforms({u_texture:0,u_textureB:1,value:k,texSize:[c,d],time:n}).draw(e)});this.setOutputData(0,this._tex)}else this.boxcolor="red"}}};LGraphTextureOperation.pixel_shader="precision highp float;\n\t\t\t\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform sampler2D u_textureB;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform vec2 texSize;\n\t\t\tuniform float time;\n\t\t\tuniform float value;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec2 uv = v_coord;\n\t\t\t\tUV_CODE;\n\t\t\t\tvec3 color = texture2D(u_texture, uv).rgb;\n\t\t\t\tvec3 colorB = texture2D(u_textureB, uv).rgb;\n\t\t\t\tvec3 result = color;\n\t\t\t\tfloat alpha = 1.0;\n\t\t\t\tPIXEL_CODE;\n\t\t\t\tgl_FragColor = vec4(result, alpha);\n\t\t\t}\n\t\t\t";
-LiteGraph.registerNodeType("texture/operation",LGraphTextureOperation);var LGraphTextureShader=function(){this.addOutput("Texture","Texture");this.properties={code:"",width:512,height:512};this.properties.code="\nvoid main() {\n vec2 uv = coord;\n vec3 color = vec3(0.0);\n//your code here\n\ngl_FragColor = vec4(color, 1.0);\n}\n"};LGraphTextureShader.title="Shader";LGraphTextureShader.desc="Texture shader";LGraphTextureShader.widgets_info={code:{widget:"code"},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};
-LGraphTextureShader.prototype.onExecute=function(){if(this._shader_code!=this.properties.code)if(this._shader_code=this.properties.code,this._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureShader.pixel_shader+this.properties.code))this.boxcolor="green";else{this.boxcolor="red";return}this._tex&&this._tex.width==this.properties.width&&this._tex.height==this.properties.height||(this._tex=new GL.Texture(this.properties.width,this.properties.height,{format:gl.RGBA,filter:gl.LINEAR}));var a=
-this._tex,b=this._shader,c=this.graph.getTime();a.drawTo(function(){b.uniforms({texSize:[a.width,a.height],time:c}).draw(Mesh.getScreenQuad())});this.setOutputData(0,this._tex)};LGraphTextureShader.pixel_shader="precision highp float;\n\t\t\t\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform float time;\n\t\t\t";LiteGraph.registerNodeType("texture/shader",LGraphTextureShader);var LGraphTextureToViewport=function(){this.addInput("Texture","Texture");this.properties={additive:!1,antialiasing:!1,disable_alpha:!1};
-this.size[0]=130;LGraphTextureToViewport._shader||(LGraphTextureToViewport._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureToViewport.pixel_shader))};LGraphTextureToViewport.title="to Viewport";LGraphTextureToViewport.desc="Texture to viewport";LGraphTextureToViewport.prototype.onExecute=function(){var a=this.getInputData(0);if(a)if(this.properties.disable_alpha?gl.disable(gl.BLEND):(gl.enable(gl.BLEND),this.properties.additive?gl.blendFunc(gl.SRC_ALPHA,gl.ONE):gl.blendFunc(gl.SRC_ALPHA,
-gl.ONE_MINUS_SRC_ALPHA)),gl.disable(gl.DEPTH_TEST),this.properties.antialiasing){gl.getViewport();var b=Mesh.getScreenQuad();a.bind(0);LGraphTextureToViewport._shader.uniforms({u_texture:0,uViewportSize:[a.width,a.height],inverseVP:[1/a.width,1/a.height]}).draw(b)}else a.toViewport()};LGraphTextureToViewport.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 uViewportSize;\n\t\t\tuniform vec2 inverseVP;\n\t\t\t#define FXAA_REDUCE_MIN (1.0/ 128.0)\n\t\t\t#define FXAA_REDUCE_MUL (1.0 / 8.0)\n\t\t\t#define FXAA_SPAN_MAX 8.0\n\t\t\t\n\t\t\t/* from mitsuhiko/webgl-meincraft based on the code on geeks3d.com */\n\t\t\tvec4 applyFXAA(sampler2D tex, vec2 fragCoord)\n\t\t\t{\n\t\t\t\tvec4 color = vec4(0.0);\n\t\t\t\t/*vec2 inverseVP = vec2(1.0 / uViewportSize.x, 1.0 / uViewportSize.y);*/\n\t\t\t\tvec3 rgbNW = texture2D(tex, (fragCoord + vec2(-1.0, -1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbNE = texture2D(tex, (fragCoord + vec2(1.0, -1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbSW = texture2D(tex, (fragCoord + vec2(-1.0, 1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbSE = texture2D(tex, (fragCoord + vec2(1.0, 1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbM = texture2D(tex, fragCoord * inverseVP).xyz;\n\t\t\t\tvec3 luma = vec3(0.299, 0.587, 0.114);\n\t\t\t\tfloat lumaNW = dot(rgbNW, luma);\n\t\t\t\tfloat lumaNE = dot(rgbNE, luma);\n\t\t\t\tfloat lumaSW = dot(rgbSW, luma);\n\t\t\t\tfloat lumaSE = dot(rgbSE, luma);\n\t\t\t\tfloat lumaM = dot(rgbM, luma);\n\t\t\t\tfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n\t\t\t\tfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n\t\t\t\t\n\t\t\t\tvec2 dir;\n\t\t\t\tdir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n\t\t\t\tdir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n\t\t\t\t\n\t\t\t\tfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\n\t\t\t\t\n\t\t\t\tfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\n\t\t\t\tdir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * inverseVP;\n\t\t\t\t\n\t\t\t\tvec3 rgbA = 0.5 * (texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + \n\t\t\t\t\ttexture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\n\t\t\t\tvec3 rgbB = rgbA * 0.5 + 0.25 * (texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + \n\t\t\t\t\ttexture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\n\t\t\t\t\n\t\t\t\treturn vec4(rgbA,1.0);\n\t\t\t\tfloat lumaB = dot(rgbB, luma);\n\t\t\t\tif ((lumaB < lumaMin) || (lumaB > lumaMax))\n\t\t\t\t\tcolor = vec4(rgbA, 1.0);\n\t\t\t\telse\n\t\t\t\t\tcolor = vec4(rgbB, 1.0);\n\t\t\t\treturn color;\n\t\t\t}\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t gl_FragColor = applyFXAA( u_texture, v_coord * uViewportSize) ;\n\t\t\t}\n\t\t\t";
+LiteGraph.registerNodeType("texture/operation",LGraphTextureOperation);var LGraphTextureShader=function(){this.addOutput("Texture","Texture");this.properties={code:"",width:512,height:512};this.properties.code="\nvoid main() {\n vec2 uv = coord;\n vec3 color = vec3(0.0);\n//your code here\n\ngl_FragColor = vec4(color, 1.0);\n}\n"};LGraphTextureShader.title="Shader";LGraphTextureShader.desc="Texture shader";LGraphTextureShader.widgets_info={code:{type:"code"},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};
+LGraphTextureShader.prototype.onExecute=function(){if(this.isOutputConnected(0)){if(this._shader_code!=this.properties.code)if(this._shader_code=this.properties.code,this._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureShader.pixel_shader+this.properties.code))this.boxcolor="green";else{this.boxcolor="red";return}this._tex&&this._tex.width==this.properties.width&&this._tex.height==this.properties.height||(this._tex=new GL.Texture(this.properties.width,this.properties.height,{format:gl.RGBA,
+filter:gl.LINEAR}));var a=this._tex,b=this._shader,c=this.graph.getTime();a.drawTo(function(){b.uniforms({texSize:[a.width,a.height],time:c}).draw(Mesh.getScreenQuad())});this.setOutputData(0,this._tex)}};LGraphTextureShader.pixel_shader="precision highp float;\n\t\t\t\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform float time;\n\t\t\t";LiteGraph.registerNodeType("texture/shader",LGraphTextureShader);var LGraphTextureToViewport=function(){this.addInput("Texture","Texture");this.properties={additive:!1,
+antialiasing:!1,disable_alpha:!1};this.size[0]=130;LGraphTextureToViewport._shader||(LGraphTextureToViewport._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureToViewport.pixel_shader))};LGraphTextureToViewport.title="to Viewport";LGraphTextureToViewport.desc="Texture to viewport";LGraphTextureToViewport.prototype.onExecute=function(){var a=this.getInputData(0);if(a)if(this.properties.disable_alpha?gl.disable(gl.BLEND):(gl.enable(gl.BLEND),this.properties.additive?gl.blendFunc(gl.SRC_ALPHA,
+gl.ONE):gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA)),gl.disable(gl.DEPTH_TEST),this.properties.antialiasing){gl.getViewport();var b=Mesh.getScreenQuad();a.bind(0);LGraphTextureToViewport._shader.uniforms({u_texture:0,uViewportSize:[a.width,a.height],inverseVP:[1/a.width,1/a.height]}).draw(b)}else a.toViewport()};LGraphTextureToViewport.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 uViewportSize;\n\t\t\tuniform vec2 inverseVP;\n\t\t\t#define FXAA_REDUCE_MIN (1.0/ 128.0)\n\t\t\t#define FXAA_REDUCE_MUL (1.0 / 8.0)\n\t\t\t#define FXAA_SPAN_MAX 8.0\n\t\t\t\n\t\t\t/* from mitsuhiko/webgl-meincraft based on the code on geeks3d.com */\n\t\t\tvec4 applyFXAA(sampler2D tex, vec2 fragCoord)\n\t\t\t{\n\t\t\t\tvec4 color = vec4(0.0);\n\t\t\t\t/*vec2 inverseVP = vec2(1.0 / uViewportSize.x, 1.0 / uViewportSize.y);*/\n\t\t\t\tvec3 rgbNW = texture2D(tex, (fragCoord + vec2(-1.0, -1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbNE = texture2D(tex, (fragCoord + vec2(1.0, -1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbSW = texture2D(tex, (fragCoord + vec2(-1.0, 1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbSE = texture2D(tex, (fragCoord + vec2(1.0, 1.0)) * inverseVP).xyz;\n\t\t\t\tvec3 rgbM = texture2D(tex, fragCoord * inverseVP).xyz;\n\t\t\t\tvec3 luma = vec3(0.299, 0.587, 0.114);\n\t\t\t\tfloat lumaNW = dot(rgbNW, luma);\n\t\t\t\tfloat lumaNE = dot(rgbNE, luma);\n\t\t\t\tfloat lumaSW = dot(rgbSW, luma);\n\t\t\t\tfloat lumaSE = dot(rgbSE, luma);\n\t\t\t\tfloat lumaM = dot(rgbM, luma);\n\t\t\t\tfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n\t\t\t\tfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n\t\t\t\t\n\t\t\t\tvec2 dir;\n\t\t\t\tdir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n\t\t\t\tdir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n\t\t\t\t\n\t\t\t\tfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\n\t\t\t\t\n\t\t\t\tfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\n\t\t\t\tdir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * inverseVP;\n\t\t\t\t\n\t\t\t\tvec3 rgbA = 0.5 * (texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + \n\t\t\t\t\ttexture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\n\t\t\t\tvec3 rgbB = rgbA * 0.5 + 0.25 * (texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + \n\t\t\t\t\ttexture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\n\t\t\t\t\n\t\t\t\treturn vec4(rgbA,1.0);\n\t\t\t\tfloat lumaB = dot(rgbB, luma);\n\t\t\t\tif ((lumaB < lumaMin) || (lumaB > lumaMax))\n\t\t\t\t\tcolor = vec4(rgbA, 1.0);\n\t\t\t\telse\n\t\t\t\t\tcolor = vec4(rgbB, 1.0);\n\t\t\t\treturn color;\n\t\t\t}\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t gl_FragColor = applyFXAA( u_texture, v_coord * uViewportSize) ;\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/toviewport",LGraphTextureToViewport);var LGraphTextureCopy=function(){this.addInput("Texture","Texture");this.addOutput("","Texture");this.properties={size:0,generate_mipmaps:!1,precision:LGraphTexture.DEFAULT}};LGraphTextureCopy.title="Copy";LGraphTextureCopy.desc="Copy Texture";LGraphTextureCopy.widgets_info={size:{widget:"combo",values:[0,32,64,128,256,512,1024,2048]},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureCopy.prototype.onExecute=
-function(){var a=this.getInputData(0);if(a||this._temp_texture){if(a){var b=a.width,c=a.height;0!=this.properties.size&&(c=b=this.properties.size);var d=this._temp_texture,e=a.type;this.properties.precision===LGraphTexture.LOW?e=gl.UNSIGNED_BYTE:this.properties.precision===LGraphTexture.HIGH&&(e=gl.HIGH_PRECISION_FORMAT);d&&d.width==b&&d.height==c&&d.type==e||(d=gl.LINEAR,this.properties.generate_mipmaps&&isPowerOfTwo(b)&&isPowerOfTwo(c)&&(d=gl.LINEAR_MIPMAP_LINEAR),this._temp_texture=new GL.Texture(b,
-c,{type:e,format:gl.RGBA,minFilter:d,magFilter:gl.LINEAR}));a.copyTo(this._temp_texture);this.properties.generate_mipmaps&&(this._temp_texture.bind(0),gl.generateMipmap(this._temp_texture.texture_type),this._temp_texture.unbind(0))}this.setOutputData(0,this._temp_texture)}};LiteGraph.registerNodeType("texture/copy",LGraphTextureCopy);var LGraphTextureAverage=function(){this.addInput("Texture","Texture");this.addOutput("","Texture");this.properties={low_precision:!1}};LGraphTextureAverage.title="Average";
-LGraphTextureAverage.desc="Compute the total average of a texture and stores it as a 1x1 pixel texture";LGraphTextureAverage.prototype.onExecute=function(){var a=this.getInputData(0);if(a){if(!LGraphTextureAverage._shader){LGraphTextureAverage._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureAverage.pixel_shader);for(var b=new Float32Array(32),c=0;32>c;++c)b[c]=Math.random();LGraphTextureAverage._shader.uniforms({u_samples_a:b.subarray(0,16),u_samples_b:b.subarray(16,32)})}b=this._temp_texture;
-c=this.properties.low_precision?gl.UNSIGNED_BYTE:a.type;b&&b.type==c||(this._temp_texture=new GL.Texture(1,1,{type:c,format:gl.RGBA,filter:gl.NEAREST}));var d=LGraphTextureAverage._shader;this._temp_texture.drawTo(function(){a.toViewport(d,{u_texture:0})});this.setOutputData(0,this._temp_texture)}};LGraphTextureAverage.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tuniform mat4 u_samples_a;\n\t\t\tuniform mat4 u_samples_b;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tvarying vec2 v_coord;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = vec4(0.0);\n\t\t\t\tfor(int i = 0; i < 4; ++i)\n\t\t\t\t\tfor(int j = 0; j < 4; ++j)\n\t\t\t\t\t{\n\t\t\t\t\t\tcolor += texture2D(u_texture, vec2( u_samples_a[i][j], u_samples_b[i][j] ) );\n\t\t\t\t\t\tcolor += texture2D(u_texture, vec2( 1.0 - u_samples_a[i][j], u_samples_b[i][j] ) );\n\t\t\t\t\t}\n\t\t\t gl_FragColor = color * 0.03125;\n\t\t\t}\n\t\t\t";
+function(){var a=this.getInputData(0);if((a||this._temp_texture)&&this.isOutputConnected(0)){if(a){var b=a.width,c=a.height;0!=this.properties.size&&(c=b=this.properties.size);var d=this._temp_texture,e=a.type;this.properties.precision===LGraphTexture.LOW?e=gl.UNSIGNED_BYTE:this.properties.precision===LGraphTexture.HIGH&&(e=gl.HIGH_PRECISION_FORMAT);d&&d.width==b&&d.height==c&&d.type==e||(d=gl.LINEAR,this.properties.generate_mipmaps&&isPowerOfTwo(b)&&isPowerOfTwo(c)&&(d=gl.LINEAR_MIPMAP_LINEAR),this._temp_texture=
+new GL.Texture(b,c,{type:e,format:gl.RGBA,minFilter:d,magFilter:gl.LINEAR}));a.copyTo(this._temp_texture);this.properties.generate_mipmaps&&(this._temp_texture.bind(0),gl.generateMipmap(this._temp_texture.texture_type),this._temp_texture.unbind(0))}this.setOutputData(0,this._temp_texture)}};LiteGraph.registerNodeType("texture/copy",LGraphTextureCopy);var LGraphTextureAverage=function(){this.addInput("Texture","Texture");this.addOutput("","Texture");this.properties={low_precision:!1}};LGraphTextureAverage.title=
+"Average";LGraphTextureAverage.desc="Compute the total average of a texture and stores it as a 1x1 pixel texture";LGraphTextureAverage.prototype.onExecute=function(){var a=this.getInputData(0);if(a&&this.isOutputConnected(0)){if(!LGraphTextureAverage._shader){LGraphTextureAverage._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureAverage.pixel_shader);for(var b=new Float32Array(32),c=0;32>c;++c)b[c]=Math.random();LGraphTextureAverage._shader.uniforms({u_samples_a:b.subarray(0,16),u_samples_b:b.subarray(16,
+32)})}b=this._temp_texture;c=this.properties.low_precision?gl.UNSIGNED_BYTE:a.type;b&&b.type==c||(this._temp_texture=new GL.Texture(1,1,{type:c,format:gl.RGBA,filter:gl.NEAREST}));var d=LGraphTextureAverage._shader;this._temp_texture.drawTo(function(){a.toViewport(d,{u_texture:0})});this.setOutputData(0,this._temp_texture)}};LGraphTextureAverage.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tuniform mat4 u_samples_a;\n\t\t\tuniform mat4 u_samples_b;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tvarying vec2 v_coord;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = vec4(0.0);\n\t\t\t\tfor(int i = 0; i < 4; ++i)\n\t\t\t\t\tfor(int j = 0; j < 4; ++j)\n\t\t\t\t\t{\n\t\t\t\t\t\tcolor += texture2D(u_texture, vec2( u_samples_a[i][j], u_samples_b[i][j] ) );\n\t\t\t\t\t\tcolor += texture2D(u_texture, vec2( 1.0 - u_samples_a[i][j], u_samples_b[i][j] ) );\n\t\t\t\t\t}\n\t\t\t gl_FragColor = color * 0.03125;\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/average",LGraphTextureAverage);var LGraphImageToTexture=function(){this.addInput("Image","image");this.addOutput("","Texture");this.properties={}};LGraphImageToTexture.title="Image to Texture";LGraphImageToTexture.desc="Uploads an image to the GPU";LGraphImageToTexture.prototype.onExecute=function(){var a=this.getInputData(0);if(a){var b=a.videoWidth||a.width,c=a.videoHeight||a.height;if(a.gltexture)this.setOutputData(0,a.gltexture);else{var d=this._temp_texture;
d&&d.width==b&&d.height==c||(this._temp_texture=new GL.Texture(b,c,{format:gl.RGBA,filter:gl.LINEAR}));try{this._temp_texture.uploadImage(a)}catch(e){console.error("image comes from an unsafe location, cannot be uploaded to webgl");return}this.setOutputData(0,this._temp_texture)}}};LiteGraph.registerNodeType("texture/imageToTexture",LGraphImageToTexture);var LGraphTextureLUT=function(){this.addInput("Texture","Texture");this.addInput("LUT","Texture");this.addInput("Intensity","number");this.addOutput("",
-"Texture");this.properties={intensity:1,precision:LGraphTexture.DEFAULT,texture:null};LGraphTextureLUT._shader||(LGraphTextureLUT._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureLUT.pixel_shader))};LGraphTextureLUT.widgets_info={precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureLUT.title="LUT";LGraphTextureLUT.desc="Apply LUT to Texture";LGraphTextureLUT.widgets_info={texture:{widget:"texture"}};LGraphTextureLUT.prototype.onExecute=function(){var a=this.getInputData(0);
-if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else if(a){var b=this.getInputData(1);b||(b=LGraphTexture.getTexture(this.properties.texture));if(b){b.bind(0);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindTexture(gl.TEXTURE_2D,null);var c=this.properties.intensity;this.isInputConnected(2)&&(this.properties.intensity=
-c=this.getInputData(2));this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);this._tex.drawTo(function(){b.bind(1);a.toViewport(LGraphTextureLUT._shader,{u_texture:0,u_textureB:1,u_amount:c})});this.setOutputData(0,this._tex)}else this.setOutputData(0,a)}};LGraphTextureLUT.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform sampler2D u_textureB;\n\t\t\tuniform float u_amount;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\t lowp vec4 textureColor = clamp( texture2D(u_texture, v_coord), vec4(0.0), vec4(1.0) );\n\t\t\t\t mediump float blueColor = textureColor.b * 63.0;\n\t\t\t\t mediump vec2 quad1;\n\t\t\t\t quad1.y = floor(floor(blueColor) / 8.0);\n\t\t\t\t quad1.x = floor(blueColor) - (quad1.y * 8.0);\n\t\t\t\t mediump vec2 quad2;\n\t\t\t\t quad2.y = floor(ceil(blueColor) / 8.0);\n\t\t\t\t quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n\t\t\t\t highp vec2 texPos1;\n\t\t\t\t texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n\t\t\t\t texPos1.y = 1.0 - ((quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g));\n\t\t\t\t highp vec2 texPos2;\n\t\t\t\t texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n\t\t\t\t texPos2.y = 1.0 - ((quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g));\n\t\t\t\t lowp vec4 newColor1 = texture2D(u_textureB, texPos1);\n\t\t\t\t lowp vec4 newColor2 = texture2D(u_textureB, texPos2);\n\t\t\t\t lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n\t\t\t\t gl_FragColor = vec4( mix( textureColor.rgb, newColor.rgb, u_amount), textureColor.w);\n\t\t\t}\n\t\t\t";
+"Texture");this.properties={intensity:1,precision:LGraphTexture.DEFAULT,texture:null};LGraphTextureLUT._shader||(LGraphTextureLUT._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureLUT.pixel_shader))};LGraphTextureLUT.widgets_info={precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureLUT.title="LUT";LGraphTextureLUT.desc="Apply LUT to Texture";LGraphTextureLUT.widgets_info={texture:{widget:"texture"}};LGraphTextureLUT.prototype.onExecute=function(){if(this.isOutputConnected(0)){var a=
+this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else if(a){var b=this.getInputData(1);b||(b=LGraphTexture.getTexture(this.properties.texture));if(b){b.bind(0);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindTexture(gl.TEXTURE_2D,null);var c=this.properties.intensity;this.isInputConnected(2)&&
+(this.properties.intensity=c=this.getInputData(2));this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);this._tex.drawTo(function(){b.bind(1);a.toViewport(LGraphTextureLUT._shader,{u_texture:0,u_textureB:1,u_amount:c})});this.setOutputData(0,this._tex)}else this.setOutputData(0,a)}}};LGraphTextureLUT.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform sampler2D u_textureB;\n\t\t\tuniform float u_amount;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\t lowp vec4 textureColor = clamp( texture2D(u_texture, v_coord), vec4(0.0), vec4(1.0) );\n\t\t\t\t mediump float blueColor = textureColor.b * 63.0;\n\t\t\t\t mediump vec2 quad1;\n\t\t\t\t quad1.y = floor(floor(blueColor) / 8.0);\n\t\t\t\t quad1.x = floor(blueColor) - (quad1.y * 8.0);\n\t\t\t\t mediump vec2 quad2;\n\t\t\t\t quad2.y = floor(ceil(blueColor) / 8.0);\n\t\t\t\t quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n\t\t\t\t highp vec2 texPos1;\n\t\t\t\t texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n\t\t\t\t texPos1.y = 1.0 - ((quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g));\n\t\t\t\t highp vec2 texPos2;\n\t\t\t\t texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n\t\t\t\t texPos2.y = 1.0 - ((quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g));\n\t\t\t\t lowp vec4 newColor1 = texture2D(u_textureB, texPos1);\n\t\t\t\t lowp vec4 newColor2 = texture2D(u_textureB, texPos2);\n\t\t\t\t lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n\t\t\t\t gl_FragColor = vec4( mix( textureColor.rgb, newColor.rgb, u_amount), textureColor.w);\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/LUT",LGraphTextureLUT);var LGraphTextureChannels=function(){this.addInput("Texture","Texture");this.addOutput("R","Texture");this.addOutput("G","Texture");this.addOutput("B","Texture");this.addOutput("A","Texture");this.properties={};LGraphTextureChannels._shader||(LGraphTextureChannels._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureChannels.pixel_shader))};LGraphTextureChannels.title="Texture to Channels";LGraphTextureChannels.desc="Split texture channels";
LGraphTextureChannels.prototype.onExecute=function(){var a=this.getInputData(0);if(a){this._channels||(this._channels=Array(4));for(var b=0,c=0;4>c;c++)this.isOutputConnected(c)?(this._channels[c]&&this._channels[c].width==a.width&&this._channels[c].height==a.height&&this._channels[c].type==a.type||(this._channels[c]=new GL.Texture(a.width,a.height,{type:a.type,format:gl.RGBA,filter:gl.LINEAR})),b++):this._channels[c]=null;if(b){gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);for(var d=Mesh.getScreenQuad(),
e=LGraphTextureChannels._shader,f=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],c=0;4>c;c++)this._channels[c]&&(this._channels[c].drawTo(function(){a.bind(0);e.uniforms({u_texture:0,u_mask:f[c]}).draw(d)}),this.setOutputData(c,this._channels[c]))}}};LGraphTextureChannels.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec4 u_mask;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t gl_FragColor = vec4( vec3( length( texture2D(u_texture, v_coord) * u_mask )), 1.0 );\n\t\t\t}\n\t\t\t";
@@ -257,19 +260,19 @@ LiteGraph.registerNodeType("texture/channelsTexture",LGraphChannelsTexture);var
this.inputs.length;e++){var f=this.inputs[e],g=this.getInputData(e);void 0!==g&&(this.properties[f.name]=g)}var h=this._uniforms;this._uniforms.u_angle=this.properties.angle*DEG2RAD;this._uniforms.u_scale=this.properties.scale;vec3.copy(h.u_colorA,c);vec3.copy(h.u_colorB,d);c=parseInt(this.properties.texture_size);this._tex&&this._tex.width==c||(this._tex=new GL.Texture(c,c,{format:gl.RGB,filter:gl.LINEAR}));this._tex.drawTo(function(){b.uniforms(h).draw(a)});this.setOutputData(0,this._tex)};LGraphTextureGradient.prototype.onGetInputs=
function(){return[["angle","number"],["scale","number"]]};LGraphTextureGradient.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform float u_angle;\n\t\t\tuniform float u_scale;\n\t\t\tuniform vec3 u_colorA;\n\t\t\tuniform vec3 u_colorB;\n\t\t\t\n\t\t\tvec2 rotate(vec2 v, float angle)\n\t\t\t{\n\t\t\t\tvec2 result;\n\t\t\t\tfloat _cos = cos(angle);\n\t\t\t\tfloat _sin = sin(angle);\n\t\t\t\tresult.x = v.x * _cos - v.y * _sin;\n\t\t\t\tresult.y = v.x * _sin + v.y * _cos;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tvoid main() {\n\t\t\t\tfloat f = (rotate(u_scale * (v_coord - vec2(0.5)), u_angle) + vec2(0.5)).x;\n\t\t\t\tvec3 color = mix(u_colorA,u_colorB,clamp(f,0.0,1.0));\n\t\t\t gl_FragColor = vec4(color,1.0);\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/gradient",LGraphTextureGradient);var LGraphTextureMix=function(){this.addInput("A","Texture");this.addInput("B","Texture");this.addInput("Mixer","Texture");this.addOutput("Texture","Texture");this.properties={precision:LGraphTexture.DEFAULT};LGraphTextureMix._shader||(LGraphTextureMix._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureMix.pixel_shader))};LGraphTextureMix.title="Mix";LGraphTextureMix.desc="Generates a texture mixing two textures";LGraphTextureMix.widgets_info=
-{precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureMix.prototype.onExecute=function(){var a=this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else{var b=this.getInputData(1),c=this.getInputData(2);if(a&&b&&c){this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var d=Mesh.getScreenQuad(),e=LGraphTextureMix._shader;this._tex.drawTo(function(){a.bind(0);
+{precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureMix.prototype.onExecute=function(){var a=this.getInputData(0);if(this.isOutputConnected(0))if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else{var b=this.getInputData(1),c=this.getInputData(2);if(a&&b&&c){this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var d=Mesh.getScreenQuad(),e=LGraphTextureMix._shader;this._tex.drawTo(function(){a.bind(0);
b.bind(1);c.bind(2);e.uniforms({u_textureA:0,u_textureB:1,u_textureMix:2}).draw(d)});this.setOutputData(0,this._tex)}}};LGraphTextureMix.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_textureA;\n\t\t\tuniform sampler2D u_textureB;\n\t\t\tuniform sampler2D u_textureMix;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t gl_FragColor = mix( texture2D(u_textureA, v_coord), texture2D(u_textureB, v_coord), texture2D(u_textureMix, v_coord) );\n\t\t\t}\n\t\t\t";
-LiteGraph.registerNodeType("texture/mix",LGraphTextureMix);var LGraphTextureEdges=function(){this.addInput("Tex.","Texture");this.addOutput("Edges","Texture");this.properties={invert:!0,precision:LGraphTexture.DEFAULT};LGraphTextureEdges._shader||(LGraphTextureEdges._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureEdges.pixel_shader))};LGraphTextureEdges.title="Edges";LGraphTextureEdges.desc="Detects edges";LGraphTextureEdges.widgets_info={precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};
-LGraphTextureEdges.prototype.onExecute=function(){var a=this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else if(a){this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var b=Mesh.getScreenQuad(),c=LGraphTextureEdges._shader,d=this.properties.invert;this._tex.drawTo(function(){a.bind(0);c.uniforms({u_texture:0,u_isize:[1/a.width,1/a.height],u_invert:d?1:0}).draw(b)});this.setOutputData(0,
-this._tex)}};LGraphTextureEdges.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_isize;\n\t\t\tuniform int u_invert;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 center = texture2D(u_texture, v_coord);\n\t\t\t\tvec4 up = texture2D(u_texture, v_coord + u_isize * vec2(0.0,1.0) );\n\t\t\t\tvec4 down = texture2D(u_texture, v_coord + u_isize * vec2(0.0,-1.0) );\n\t\t\t\tvec4 left = texture2D(u_texture, v_coord + u_isize * vec2(1.0,0.0) );\n\t\t\t\tvec4 right = texture2D(u_texture, v_coord + u_isize * vec2(-1.0,0.0) );\n\t\t\t\tvec4 diff = abs(center - up) + abs(center - down) + abs(center - left) + abs(center - right);\n\t\t\t\tif(u_invert == 1)\n\t\t\t\t\tdiff.xyz = vec3(1.0) - diff.xyz;\n\t\t\t gl_FragColor = vec4( diff.xyz, center.a );\n\t\t\t}\n\t\t\t";
+LiteGraph.registerNodeType("texture/mix",LGraphTextureMix);var LGraphTextureEdges=function(){this.addInput("Tex.","Texture");this.addOutput("Edges","Texture");this.properties={invert:!0,factor:1,precision:LGraphTexture.DEFAULT};LGraphTextureEdges._shader||(LGraphTextureEdges._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureEdges.pixel_shader))};LGraphTextureEdges.title="Edges";LGraphTextureEdges.desc="Detects edges";LGraphTextureEdges.widgets_info={precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};
+LGraphTextureEdges.prototype.onExecute=function(){if(this.isOutputConnected(0)){var a=this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else if(a){this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var b=Mesh.getScreenQuad(),c=LGraphTextureEdges._shader,d=this.properties.invert,e=this.properties.factor;this._tex.drawTo(function(){a.bind(0);c.uniforms({u_texture:0,u_isize:[1/
+a.width,1/a.height],u_factor:e,u_invert:d?1:0}).draw(b)});this.setOutputData(0,this._tex)}}};LGraphTextureEdges.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_isize;\n\t\t\tuniform int u_invert;\n\t\t\tuniform float u_factor;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 center = texture2D(u_texture, v_coord);\n\t\t\t\tvec4 up = texture2D(u_texture, v_coord + u_isize * vec2(0.0,1.0) );\n\t\t\t\tvec4 down = texture2D(u_texture, v_coord + u_isize * vec2(0.0,-1.0) );\n\t\t\t\tvec4 left = texture2D(u_texture, v_coord + u_isize * vec2(1.0,0.0) );\n\t\t\t\tvec4 right = texture2D(u_texture, v_coord + u_isize * vec2(-1.0,0.0) );\n\t\t\t\tvec4 diff = abs(center - up) + abs(center - down) + abs(center - left) + abs(center - right);\n\t\t\t\tdiff *= u_factor;\n\t\t\t\tif(u_invert == 1)\n\t\t\t\t\tdiff.xyz = vec3(1.0) - diff.xyz;\n\t\t\t gl_FragColor = vec4( diff.xyz, center.a );\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/edges",LGraphTextureEdges);var LGraphTextureDepthRange=function(){this.addInput("Texture","Texture");this.addInput("Distance","number");this.addInput("Range","number");this.addOutput("Texture","Texture");this.properties={distance:100,range:50,high_precision:!1};LGraphTextureDepthRange._shader||(LGraphTextureDepthRange._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureDepthRange.pixel_shader))};LGraphTextureDepthRange.title="Depth Range";LGraphTextureDepthRange.desc=
-"Generates a texture with a depth range";LGraphTextureDepthRange.prototype.onExecute=function(){var a=this.getInputData(0);if(a){var b=gl.UNSIGNED_BYTE;this.properties.high_precision&&(b=gl.half_float_ext?gl.HALF_FLOAT_OES:gl.FLOAT);this._temp_texture&&this._temp_texture.type==b&&this._temp_texture.width==a.width&&this._temp_texture.height==a.height||(this._temp_texture=new GL.Texture(a.width,a.height,{type:b,format:gl.RGBA,filter:gl.LINEAR}));var c=this.properties.distance;this.isInputConnected(1)&&
-(c=this.getInputData(1),this.properties.distance=c);var d=this.properties.range;this.isInputConnected(2)&&(d=this.getInputData(2),this.properties.range=d);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var e=Mesh.getScreenQuad(),f=LGraphTextureDepthRange._shader,g=[Renderer._current_camera.near,Renderer._current_camera.far];this._temp_texture.drawTo(function(){a.bind(0);f.uniforms({u_texture:0,u_distance:c,u_range:d,u_camera_planes:g}).draw(e)});this.setOutputData(0,this._temp_texture)}};LGraphTextureDepthRange.pixel_shader=
-"precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_camera_planes;\n\t\t\tuniform float u_distance;\n\t\t\tuniform float u_range;\n\t\t\t\n\t\t\tfloat LinearDepth()\n\t\t\t{\n\t\t\t\tfloat n = u_camera_planes.x;\n\t\t\t\tfloat f = u_camera_planes.y;\n\t\t\t\treturn (2.0 * n) / (f + n - texture2D(u_texture, v_coord).x * (f - n));\n\t\t\t}\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tfloat diff = abs(LinearDepth() * u_camera_planes.y - u_distance);\n\t\t\t\tfloat dof = 1.0;\n\t\t\t\tif(diff <= u_range)\n\t\t\t\t\tdof = diff / u_range;\n\t\t\t gl_FragColor = vec4(dof);\n\t\t\t}\n\t\t\t";
+"Generates a texture with a depth range";LGraphTextureDepthRange.prototype.onExecute=function(){if(this.isOutputConnected(0)){var a=this.getInputData(0);if(a){var b=gl.UNSIGNED_BYTE;this.properties.high_precision&&(b=gl.half_float_ext?gl.HALF_FLOAT_OES:gl.FLOAT);this._temp_texture&&this._temp_texture.type==b&&this._temp_texture.width==a.width&&this._temp_texture.height==a.height||(this._temp_texture=new GL.Texture(a.width,a.height,{type:b,format:gl.RGBA,filter:gl.LINEAR}));var c=this.properties.distance;
+this.isInputConnected(1)&&(c=this.getInputData(1),this.properties.distance=c);var d=this.properties.range;this.isInputConnected(2)&&(d=this.getInputData(2),this.properties.range=d);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var e=Mesh.getScreenQuad(),f=LGraphTextureDepthRange._shader,g=[Renderer._current_camera.near,Renderer._current_camera.far];this._temp_texture.drawTo(function(){a.bind(0);f.uniforms({u_texture:0,u_distance:c,u_range:d,u_camera_planes:g}).draw(e)});this.setOutputData(0,this._temp_texture)}}};
+LGraphTextureDepthRange.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_camera_planes;\n\t\t\tuniform float u_distance;\n\t\t\tuniform float u_range;\n\t\t\t\n\t\t\tfloat LinearDepth()\n\t\t\t{\n\t\t\t\tfloat n = u_camera_planes.x;\n\t\t\t\tfloat f = u_camera_planes.y;\n\t\t\t\treturn (2.0 * n) / (f + n - texture2D(u_texture, v_coord).x * (f - n));\n\t\t\t}\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tfloat diff = abs(LinearDepth() * u_camera_planes.y - u_distance);\n\t\t\t\tfloat dof = 1.0;\n\t\t\t\tif(diff <= u_range)\n\t\t\t\t\tdof = diff / u_range;\n\t\t\t gl_FragColor = vec4(dof);\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/depth_range",LGraphTextureDepthRange);var LGraphTextureBlur=function(){this.addInput("Texture","Texture");this.addInput("Iterations","number");this.addInput("Intensity","number");this.addOutput("Blurred","Texture");this.properties={intensity:1,iterations:1,preserve_aspect:!1,scale:[1,1]};LGraphTextureBlur._shader||(LGraphTextureBlur._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureBlur.pixel_shader))};LGraphTextureBlur.title="Blur";LGraphTextureBlur.desc=
-"Blur a texture";LGraphTextureBlur.max_iterations=20;LGraphTextureBlur.prototype.onExecute=function(){var a=this.getInputData(0);if(a){var b=this._temp_texture;b&&b.width==a.width&&b.height==a.height&&b.type==a.type||(this._temp_texture=new GL.Texture(a.width,a.height,{type:a.type,format:gl.RGBA,filter:gl.LINEAR}),this._final_texture=new GL.Texture(a.width,a.height,{type:a.type,format:gl.RGBA,filter:gl.LINEAR}));b=this.properties.iterations;this.isInputConnected(1)&&(b=this.getInputData(1),this.properties.iterations=
-b);b=Math.min(Math.floor(b),LGraphTextureBlur.max_iterations);if(0==b)this.setOutputData(0,a);else{var c=this.properties.intensity;this.isInputConnected(2)&&(c=this.getInputData(2),this.properties.intensity=c);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var d=Mesh.getScreenQuad(),e=LGraphTextureBlur._shader,f=this.properties.scale||[1,1],g=LiteGraph.camera_aspect;g||void 0===window.gl||(g=gl.canvas.height/gl.canvas.width);g||(g=1);for(var h=a,g=this.properties.preserve_aspect?g:1,a=0;a=this.size[1]||!this._video||(a.save(),a.webgl?this._temp_texture&&a.drawImage(this._temp_texture,0,0,this.size[0],this.size[1]):(a.translate(0,this.size[1]),a.scale(1,-1),a.drawImage(this._video,0,0,this.size[0],this.size[1])),a.restore())};LGraphTextureWebcam.prototype.onExecute=function(){null!=this._webcam_stream||this._waiting_confirmation||this.openStream();if(this._video&&
@@ -282,8 +285,8 @@ LGraphFXLens.widgets_info={precision:{widget:"combo",values:LGraphTexture.MODE_V
LiteGraph.registerNodeType("fx/lens",LGraphFXLens);window.LGraphFXLens=LGraphFXLens;var LGraphFXBokeh=function(){this.addInput("Texture","Texture");this.addInput("Blurred","Texture");this.addInput("Mask","Texture");this.addInput("Threshold","number");this.addOutput("Texture","Texture");this.properties={shape:"",size:10,alpha:1,threshold:1,high_precision:!1}};LGraphFXBokeh.title="Bokeh";LGraphFXBokeh.desc="applies an Bokeh effect";LGraphFXBokeh.widgets_info={shape:{widget:"texture"}};LGraphFXBokeh.prototype.onExecute=
function(){var a=this.getInputData(0),b=this.getInputData(1),c=this.getInputData(2);if(a&&c&&this.properties.shape){b||(b=a);var d=LGraphTexture.getTexture(this.properties.shape);if(d){var e=this.properties.threshold;this.isInputConnected(3)&&(e=this.getInputData(3),this.properties.threshold=e);var f=gl.UNSIGNED_BYTE;this.properties.high_precision&&(f=gl.half_float_ext?gl.HALF_FLOAT_OES:gl.FLOAT);this._temp_texture&&this._temp_texture.type==f&&this._temp_texture.width==a.width&&this._temp_texture.height==
a.height||(this._temp_texture=new GL.Texture(a.width,a.height,{type:f,format:gl.RGBA,filter:gl.LINEAR}));var g=LGraphFXBokeh._first_shader;g||(g=LGraphFXBokeh._first_shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphFXBokeh._first_pixel_shader));var h=LGraphFXBokeh._second_shader;h||(h=LGraphFXBokeh._second_shader=new GL.Shader(LGraphFXBokeh._second_vertex_shader,LGraphFXBokeh._second_pixel_shader));var k=this._points_mesh;k&&k._width==a.width&&k._height==a.height&&2==k._spacing||(k=this.createPointsMesh(a.width,
-a.height,2));var n=Mesh.getScreenQuad(),p=this.properties.size,l=this.properties.alpha;gl.disable(gl.DEPTH_TEST);gl.disable(gl.BLEND);this._temp_texture.drawTo(function(){a.bind(0);b.bind(1);c.bind(2);g.uniforms({u_texture:0,u_texture_blur:1,u_mask:2,u_texsize:[a.width,a.height]}).draw(n)});this._temp_texture.drawTo(function(){gl.enable(gl.BLEND);gl.blendFunc(gl.ONE,gl.ONE);a.bind(0);d.bind(3);h.uniforms({u_texture:0,u_mask:2,u_shape:3,u_alpha:l,u_threshold:e,u_pointSize:p,u_itexsize:[1/a.width,1/
-a.height]}).draw(k,gl.POINTS)});this.setOutputData(0,this._temp_texture)}}else this.setOutputData(0,a)};LGraphFXBokeh.prototype.createPointsMesh=function(a,b,c){for(var d=Math.round(a/c),e=Math.round(b/c),f=new Float32Array(d*e*2),g=-1,h=2/a*c,k=2/b*c,n=0;n= 0; i--)
{
var n = nodes_list[i];
- if(n.isPointInsideNode(x,y))
+ if(n.isPointInsideNode( x, y, 2 ))
return n;
}
return null;
@@ -1125,7 +1125,15 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
// Node CLASS *******
// *************************************************************
-/* flags:
+/*
+ title: string
+ pos: [x,y]
+ size: [x,y]
+
+ input|output: every connection
+ + { name:string, type:string, pos: [x,y]=Optional, direction: "input"|"output", links: Array });
+
+ flags:
+ skip_title_render
+ clip_area
+ unsafe_execution: not allowed for safe execution
@@ -1351,7 +1359,7 @@ LGraphNode.prototype.setOutputData = function(slot,data)
* retrieves the input data (data traveling through the connection) from one slot
* @method getInputData
* @param {number} slot
-* @return {*} data
+* @return {*} data or if it is not connected returns undefined
*/
LGraphNode.prototype.getInputData = function(slot)
{
@@ -1379,11 +1387,12 @@ LGraphNode.prototype.isInputConnected = function(slot)
* tells you info about an input connection (which node, type, etc)
* @method getInputInfo
* @param {number} slot
-* @return {Object}
+* @return {Object} object or null
*/
LGraphNode.prototype.getInputInfo = function(slot)
{
- if(!this.inputs) return null;
+ if(!this.inputs)
+ return null;
if(slot < this.inputs.length)
return this.inputs[slot];
return null;
@@ -1394,11 +1403,12 @@ LGraphNode.prototype.getInputInfo = function(slot)
* tells you info about an output connection (which node, type, etc)
* @method getOutputInfo
* @param {number} slot
-* @return {Object}
+* @return {Object} object or null
*/
LGraphNode.prototype.getOutputInfo = function(slot)
{
- if(!this.outputs) return null;
+ if(!this.outputs)
+ return null;
if(slot < this.outputs.length)
return this.outputs[slot];
return null;
@@ -1413,7 +1423,8 @@ LGraphNode.prototype.getOutputInfo = function(slot)
*/
LGraphNode.prototype.isOutputConnected = function(slot)
{
- if(!this.outputs) return null;
+ if(!this.outputs)
+ return null;
return (slot < this.outputs.length && this.outputs[slot].links && this.outputs[slot].links.length);
}
@@ -1521,7 +1532,8 @@ LGraphNode.prototype.addInput = function(name,type,extra_info)
for(var i in extra_info)
o[i] = extra_info[i];
- if(!this.inputs) this.inputs = [];
+ if(!this.inputs)
+ this.inputs = [];
this.inputs.push(o);
this.size = this.computeSize();
if(this.onInputAdded)
@@ -1590,11 +1602,44 @@ LGraphNode.prototype.computeSize = function(minHeight)
{
var rows = Math.max( this.inputs ? this.inputs.length : 1, this.outputs ? this.outputs.length : 1);
var size = new Float32Array([0,0]);
+ rows = Math.max(rows, 1);
size[1] = rows * 14 + 6;
- if(!this.inputs || this.inputs.length == 0 || !this.outputs || this.outputs.length == 0)
- size[0] = LiteGraph.NODE_WIDTH * 0.5;
- else
- size[0] = LiteGraph.NODE_WIDTH;
+
+ var font_size = 14;
+ var title_width = compute_text_size( this.title );
+ var input_width = 0;
+ var output_width = 0;
+
+ if(this.inputs)
+ for(var i = 0, l = this.inputs.length; i < l; ++i)
+ {
+ var input = this.inputs[i];
+ var text = input.label || input.name || "";
+ var text_width = compute_text_size( text );
+ if(input_width < text_width)
+ input_width = text_width;
+ }
+
+ if(this.outputs)
+ for(var i = 0, l = this.outputs.length; i < l; ++i)
+ {
+ var output = this.outputs[i];
+ var text = output.label || output.name || "";
+ var text_width = compute_text_size( text );
+ if(output_width < text_width)
+ output_width = text_width;
+ }
+
+ size[0] = Math.max( input_width + output_width + 10, title_width );
+ size[0] = Math.max( size[0], LiteGraph.NODE_WIDTH );
+
+ function compute_text_size( text )
+ {
+ if(!text)
+ return 0;
+ return font_size * text.length * 0.6;
+ }
+
return size;
}
@@ -1615,21 +1660,54 @@ LGraphNode.prototype.getBounding = function()
* @param {number} y
* @return {boolean}
*/
-LGraphNode.prototype.isPointInsideNode = function(x,y)
+LGraphNode.prototype.isPointInsideNode = function(x,y, margin)
{
+ margin = margin || 0;
+
var margin_top = this.graph && this.graph.isLive() ? 0 : 20;
if(this.flags.collapsed)
{
//if ( distance([x,y], [this.pos[0] + this.size[0]*0.5, this.pos[1] + this.size[1]*0.5]) < LiteGraph.NODE_COLLAPSED_RADIUS)
- if( isInsideRectangle(x,y, this.pos[0], this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_COLLAPSED_WIDTH, LiteGraph.NODE_TITLE_HEIGHT) )
+ if( isInsideRectangle( x, y, this.pos[0] - margin, this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT - margin, LiteGraph.NODE_COLLAPSED_WIDTH + 2 * margin, LiteGraph.NODE_TITLE_HEIGHT + 2 * margin ) )
return true;
}
- else if (this.pos[0] - 4 < x && (this.pos[0] + this.size[0] + 4) > x
- && (this.pos[1] - margin_top) < y && (this.pos[1] + this.size[1]) > y)
+ else if ( (this.pos[0] - 4 - margin) < x && (this.pos[0] + this.size[0] + 4 + margin) > x
+ && (this.pos[1] - margin_top - margin) < y && (this.pos[1] + this.size[1] + margin) > y)
return true;
return false;
}
+/**
+* checks if a point is inside a node slot, and returns info about which slot
+* @method getSlotInPosition
+* @param {number} x
+* @param {number} y
+* @return {Object} if found the object contains { input|output: slot object, slot: number, link_pos: [x,y] }
+*/
+LGraphNode.prototype.getSlotInPosition = function( x, y )
+{
+ //search for inputs
+ if(this.inputs)
+ for(var i = 0, l = this.inputs.length; i < l; ++i)
+ {
+ var input = this.inputs[i];
+ var link_pos = this.getConnectionPos( true,i );
+ if( isInsideRectangle(x, y, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
+ return { input: input, slot: i, link_pos: link_pos, locked: input.locked };
+ }
+
+ if(this.outputs)
+ for(var i = 0, l = this.outputs.length; i < l; ++i)
+ {
+ var output = this.outputs[i];
+ var link_pos = this.getConnectionPos(false,i);
+ if( isInsideRectangle(x, y, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
+ return { output: output, slot: i, link_pos: link_pos, locked: output.locked };
+ }
+
+ return null;
+}
+
/**
* returns the input slot with a given name (used for dynamic slots), -1 if not found
* @method findInputSlot
@@ -1837,28 +1915,33 @@ LGraphNode.prototype.disconnectInput = function(slot)
}
var input = this.inputs[slot];
- if(!input) return false;
+ if(!input)
+ return false;
var link_id = this.inputs[slot].link;
this.inputs[slot].link = null;
//remove other side
var link_info = this.graph.links[ link_id ];
- var node = this.graph.getNodeById( link_info.origin_id );
- if(!node) return false;
-
- var output = node.outputs[ link_info.origin_slot ];
- if(!output || !output.links || output.links.length == 0)
- return false;
-
- //check outputs
- for(var i = 0, l = output.links.length; i < l; i++)
+ if( link_info )
{
- var link_id = output.links[i];
- var link_info = this.graph.links[ link_id ];
- if( link_info.target_id == this.id )
+ var node = this.graph.getNodeById( link_info.origin_id );
+ if(!node)
+ return false;
+
+ var output = node.outputs[ link_info.origin_slot ];
+ if(!output || !output.links || output.links.length == 0)
+ return false;
+
+ //check outputs
+ for(var i = 0, l = output.links.length; i < l; i++)
{
- output.links.splice(i,1);
- break;
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+ if( link_info.target_id == this.id )
+ {
+ output.links.splice(i,1);
+ break;
+ }
}
}
@@ -1874,7 +1957,7 @@ LGraphNode.prototype.disconnectInput = function(slot)
* @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot)
* @return {[x,y]} the position
**/
-LGraphNode.prototype.getConnectionPos = function(is_input,slot_number)
+LGraphNode.prototype.getConnectionPos = function(is_input, slot_number)
{
if(this.flags.collapsed)
{
@@ -2511,7 +2594,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
- var n = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes);
+ var n = this.graph.getNodeOnPos( e.canvasX, e.canvasY, this.visible_nodes );
var skip_dragging = false;
if(e.which == 1) //left button mouse
@@ -4386,16 +4469,42 @@ LGraphCanvas.prototype.getNodeMenuOptions = function(node)
return options;
}
-LGraphCanvas.prototype.processContextualMenu = function(node,event)
+LGraphCanvas.prototype.processContextualMenu = function(node, event)
{
var that = this;
var win = this.getCanvasWindow();
- var menu = LiteGraph.createContextualMenu(node ? this.getNodeMenuOptions(node) : this.getCanvasMenuOptions(), {event: event, callback: inner_option_clicked}, win);
+ var menu_info = null;
+
+ //check if mouse is in input
+ var slot = null;
+ if(node)
+ slot = node.getSlotInPosition( event.canvasX, event.canvasY );
+
+ if(slot)
+ menu_info = slot.locked ? [ "Cannot remove" ] : { "Remove Slot": slot };
+ else
+ menu_info = node ? this.getNodeMenuOptions(node) : this.getCanvasMenuOptions();
+
+ //show menu
+ if(!menu_info)
+ return;
+
+ var menu = LiteGraph.createContextualMenu( menu_info, {event: event, callback: inner_option_clicked}, win);
function inner_option_clicked(v,e)
{
- if(!v) return;
+ if(!v)
+ return;
+
+ if(v == slot)
+ {
+ if(v.input)
+ node.removeInput( slot.slot );
+ else if(v.output)
+ node.removeOutput( slot.slot );
+ return;
+ }
if(v.callback)
return v.callback(node, e, menu, that, event );
diff --git a/src/nodes/base.js b/src/nodes/base.js
old mode 100644
new mode 100755
diff --git a/src/nodes/glfx.js b/src/nodes/glfx.js
old mode 100644
new mode 100755
diff --git a/src/nodes/gltextures.js b/src/nodes/gltextures.js
old mode 100644
new mode 100755
index a8f8f9e19..48c8aaab2
--- a/src/nodes/gltextures.js
+++ b/src/nodes/gltextures.js
@@ -383,6 +383,9 @@ if(typeof(LiteGraph) != "undefined")
{
var tex = this.getInputData(0);
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
if(this.properties.precision === LGraphTexture.PASS_THROUGH)
{
this.setOutputData(0, tex);
@@ -523,12 +526,15 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureShader.title = "Shader";
LGraphTextureShader.desc = "Texture shader";
LGraphTextureShader.widgets_info = {
- "code": { widget:"code" },
+ "code": { type:"code" },
"precision": { widget:"combo", values: LGraphTexture.MODE_VALUES }
};
LGraphTextureShader.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
//replug
if(this._shader_code != this.properties.code)
{
@@ -724,6 +730,9 @@ if(typeof(LiteGraph) != "undefined")
if(!tex && !this._temp_texture)
return;
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
//copy the texture
if(tex)
{
@@ -782,7 +791,11 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureAverage.prototype.onExecute = function()
{
var tex = this.getInputData(0);
- if(!tex) return;
+ if(!tex)
+ return;
+
+ if(!this.isOutputConnected(0))
+ return; //saves work
if(!LGraphTextureAverage._shader)
{
@@ -842,7 +855,8 @@ if(typeof(LiteGraph) != "undefined")
LGraphImageToTexture.prototype.onExecute = function()
{
var img = this.getInputData(0);
- if(!img) return;
+ if(!img)
+ return;
var width = img.videoWidth || img.width;
var height = img.videoHeight || img.height;
@@ -898,6 +912,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureLUT.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
@@ -1229,6 +1246,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureMix.prototype.onExecute = function()
{
var texA = this.getInputData(0);
+
+ if(!this.isOutputConnected(0))
+ return; //saves work
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
{
@@ -1278,7 +1298,7 @@ if(typeof(LiteGraph) != "undefined")
this.addInput("Tex.","Texture");
this.addOutput("Edges","Texture");
- this.properties = { invert: true, precision: LGraphTexture.DEFAULT };
+ this.properties = { invert: true, factor: 1, precision: LGraphTexture.DEFAULT };
if(!LGraphTextureEdges._shader)
LGraphTextureEdges._shader = new GL.Shader( Shader.SCREEN_VERTEX_SHADER, LGraphTextureEdges.pixel_shader );
@@ -1293,6 +1313,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureEdges.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
@@ -1311,10 +1334,11 @@ if(typeof(LiteGraph) != "undefined")
var mesh = Mesh.getScreenQuad();
var shader = LGraphTextureEdges._shader;
var invert = this.properties.invert;
+ var factor = this.properties.factor;
this._tex.drawTo( function() {
tex.bind(0);
- shader.uniforms({u_texture:0, u_isize:[1/tex.width,1/tex.height], u_invert: invert ? 1 : 0}).draw(mesh);
+ shader.uniforms({u_texture:0, u_isize:[1/tex.width,1/tex.height], u_factor: factor, u_invert: invert ? 1 : 0}).draw(mesh);
});
this.setOutputData(0, this._tex);
@@ -1326,6 +1350,7 @@ if(typeof(LiteGraph) != "undefined")
uniform sampler2D u_texture;\n\
uniform vec2 u_isize;\n\
uniform int u_invert;\n\
+ uniform float u_factor;\n\
\n\
void main() {\n\
vec4 center = texture2D(u_texture, v_coord);\n\
@@ -1334,6 +1359,7 @@ if(typeof(LiteGraph) != "undefined")
vec4 left = texture2D(u_texture, v_coord + u_isize * vec2(1.0,0.0) );\n\
vec4 right = texture2D(u_texture, v_coord + u_isize * vec2(-1.0,0.0) );\n\
vec4 diff = abs(center - up) + abs(center - down) + abs(center - left) + abs(center - right);\n\
+ diff *= u_factor;\n\
if(u_invert == 1)\n\
diff.xyz = vec3(1.0) - diff.xyz;\n\
gl_FragColor = vec4( diff.xyz, center.a );\n\
@@ -1360,6 +1386,9 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureDepthRange.prototype.onExecute = function()
{
+ if(!this.isOutputConnected(0))
+ return; //saves work
+
var tex = this.getInputData(0);
if(!tex) return;
@@ -1451,7 +1480,11 @@ if(typeof(LiteGraph) != "undefined")
LGraphTextureBlur.prototype.onExecute = function()
{
var tex = this.getInputData(0);
- if(!tex) return;
+ if(!tex)
+ return;
+
+ if(!this.isOutputConnected(0))
+ return; //saves work
var temp = this._temp_texture;
@@ -1638,7 +1671,8 @@ if(typeof(LiteGraph) != "undefined")
if(this._webcam_stream == null && !this._waiting_confirmation)
this.openStream();
- if(!this._video || !this._video.videoWidth) return;
+ if(!this._video || !this._video.videoWidth)
+ return;
var width = this._video.videoWidth;
var height = this._video.videoHeight;
diff --git a/src/nodes/image.js b/src/nodes/image.js
old mode 100644
new mode 100755
diff --git a/src/nodes/input.js b/src/nodes/input.js
old mode 100644
new mode 100755
diff --git a/src/nodes/interface.js b/src/nodes/interface.js
old mode 100644
new mode 100755
diff --git a/src/nodes/logic.js b/src/nodes/logic.js
old mode 100644
new mode 100755
diff --git a/src/nodes/math.js b/src/nodes/math.js
old mode 100644
new mode 100755
index 1659fa7a4..9619b1a73
--- a/src/nodes/math.js
+++ b/src/nodes/math.js
@@ -141,6 +141,37 @@ MathFrac.prototype.onExecute = function()
LiteGraph.registerNodeType("math/frac",MathFrac);
+//Math Floor
+function MathSmoothStep()
+{
+ this.addInput("in","number");
+ this.addOutput("out","number");
+ this.size = [60,20];
+ this.properties = { A: 0, B: 1 };
+}
+
+MathSmoothStep.title = "Smoothstep";
+MathSmoothStep.desc = "Smoothstep";
+
+MathSmoothStep.prototype.onExecute = function()
+{
+ var v = this.getInputData(0);
+ if(v === undefined)
+ return;
+
+ var edge0 = this.properties.A;
+ var edge1 = this.properties.B;
+
+ // Scale, bias and saturate x to 0..1 range
+ v = Math.clamp((v - edge0)/(edge1 - edge0), 0.0, 1.0);
+ // Evaluate polynomial
+ v = v*v*(3 - 2*v);
+
+ this.setOutputData(0, v );
+}
+
+LiteGraph.registerNodeType("math/smoothstep", MathSmoothStep );
+
//Math scale
function MathScale()
{
diff --git a/src/nodes/others.js b/src/nodes/others.js
old mode 100644
new mode 100755
diff --git a/style.css b/style.css
old mode 100644
new mode 100755
diff --git a/utils/builder.py b/utils/builder.py
old mode 100644
new mode 100755
diff --git a/utils/deploy_files.txt b/utils/deploy_files.txt
old mode 100644
new mode 100755
diff --git a/utils/temp.js b/utils/temp.js
old mode 100644
new mode 100755