From 719a74a0d86d7f9f80ac3c4059c2ff9b7b7a0fee Mon Sep 17 00:00:00 2001 From: atlasan Date: Sat, 9 Oct 2021 11:51:07 +0200 Subject: [PATCH] Integration and Fixes - few new nodes - onAction, onExecute, onTrigger has the third parameters for additional options - onAction has to refresh the getInputData values for future behaviours - prefer 0 or "*" for slot type instead of empty string "" --- src/nodes/audio.js | 2 +- src/nodes/base.js | 157 ++- src/nodes/events.js | 54 +- src/nodes/interface.js | 3 +- src/nodes/logic.js | 116 ++ src/nodes/math.js | 2658 ++++++++++++++++++++-------------------- src/nodes/others.js | 1 + src/nodes/strings.js | 8 +- 8 files changed, 1616 insertions(+), 1383 deletions(-) diff --git a/src/nodes/audio.js b/src/nodes/audio.js index ca35c6990..2c02bdf33 100644 --- a/src/nodes/audio.js +++ b/src/nodes/audio.js @@ -997,7 +997,7 @@ LiteGraph.registerNodeType("audio/waveShaper", LGAudioWaveShaper); this.audionode = LGAudio.getAudioContext().createGain(); this.audionode.gain.value = 0; this.addInput("in", "audio"); - this.addInput("gate", "bool"); + this.addInput("gate", "boolean"); this.addOutput("out", "audio"); this.gate = false; } diff --git a/src/nodes/base.js b/src/nodes/base.js index 7546d67af..867e4f984 100755 --- a/src/nodes/base.js +++ b/src/nodes/base.js @@ -724,9 +724,10 @@ LiteGraph.registerNodeType("basic/const", ConstantNumber); function ConstantBoolean() { - this.addOutput("", "boolean"); + this.addOutput("bool", "boolean"); this.addProperty("value", true); this.widget = this.addWidget("toggle","value",true,"value"); + this.serialize_widgets = true; this.widgets_up = true; this.size = [140, 30]; } @@ -753,7 +754,7 @@ LiteGraph.registerNodeType("basic/boolean", ConstantBoolean); function ConstantString() { - this.addOutput("", "string"); + this.addOutput("string", "string"); this.addProperty("value", ""); this.widget = this.addWidget("text","value","","value"); //link to property value this.widgets_up = true; @@ -800,8 +801,8 @@ LiteGraph.registerNodeType( "basic/object", ConstantObject ); function ConstantFile() { - this.addInput("url", ""); - this.addOutput("", ""); + this.addInput("url", "string"); + this.addOutput("file", "string"); this.addProperty("url", ""); this.addProperty("type", "text"); this.widget = this.addWidget("text","url","","url"); @@ -899,7 +900,7 @@ //to store json objects function ConstantData() { - this.addOutput("", ""); + this.addOutput("data", "object"); this.addProperty("value", ""); this.widget = this.addWidget("text","json","","value"); this.widgets_up = true; @@ -934,10 +935,10 @@ //to store json objects function ConstantArray() { - this._value = []; - this.addInput("", ""); - this.addOutput("", "array"); - this.addOutput("length", "number"); + this._value = []; + this.addInput("json", ""); + this.addOutput("arrayOut", "array"); + this.addOutput("length", "number"); this.addProperty("value", "[]"); this.widget = this.addWidget("text","array",this.properties.value,"value"); this.widgets_up = true; @@ -974,7 +975,7 @@ for(var i = 0; i < v.length; ++i) this._value[i] = v[i]; } - this.setOutputData(0, this._value ); + this.setOutputData(0, this._value); this.setOutputData(1, this._value ? ( this._value.length || 0) : 0 ); }; @@ -988,7 +989,7 @@ this.addInput("value", ""); this.addOutput("arr", "array"); this.properties = { index: 0 }; - this.widget = this.addWidget("number","i",this.properties.index,"index"); + this.widget = this.addWidget("number","i",this.properties.index,"index",{precision: 0, step: 10, min: 0}); } SetArray.title = "Set Array"; @@ -1062,9 +1063,9 @@ LiteGraph.registerNodeType("basic/table[][]", TableElement); function ObjectProperty() { - this.addInput("obj", ""); - this.addOutput("", ""); - this.addProperty("value", ""); + this.addInput("obj", "object"); + this.addOutput("property", 0); + this.addProperty("value", 0); this.widget = this.addWidget("text","prop.","",this.setValue.bind(this) ); this.widgets_up = true; this.size = [140, 30]; @@ -1146,9 +1147,9 @@ function MergeObjects() { - this.addInput("A", ""); - this.addInput("B", ""); - this.addOutput("", ""); + this.addInput("A", "object"); + this.addInput("B", "object"); + this.addOutput("out", "object"); this._result = {}; var that = this; this.addWidget("button","clear","",function(){ @@ -1396,21 +1397,27 @@ Console.desc = "Show value inside the console"; Console.prototype.onAction = function(action, param) { + // param is the action + var msg = this.getInputData(1); //getInputDataByName("msg"); + //if (msg == null || typeof msg == "undefined") return; + if (!msg) msg = this.properties.msg; + if (!msg) msg = "Event: "+param; // msg is undefined if the slot is lost? if (action == "log") { - console.log(param); + console.log(msg); } else if (action == "warn") { - console.warn(param); + console.warn(msg); } else if (action == "error") { - console.error(param); + console.error(msg); } }; Console.prototype.onExecute = function() { - var msg = this.getInputData(1); - if (msg !== null) { + var msg = this.getInputData(1); //getInputDataByName("msg"); + if (!msg) msg = this.properties.msg; + if (msg != null && typeof msg != "undefined") { this.properties.msg = msg; + console.log(msg); } - console.log(msg); }; Console.prototype.onGetInputs = function() { @@ -1455,9 +1462,9 @@ function NodeScript() { this.size = [60, 30]; this.addProperty("onExecute", "return A;"); - this.addInput("A", ""); - this.addInput("B", ""); - this.addOutput("out", ""); + this.addInput("A", 0); + this.addInput("B", 0); + this.addOutput("out", 0); this._func = null; this.data = {}; @@ -1534,4 +1541,102 @@ }; LiteGraph.registerNodeType("basic/script", NodeScript); + + + function GenericCompare() { + this.addInput("A", 0); + this.addInput("B", 0); + this.addOutput("true", "boolean"); + this.addOutput("false", "boolean"); + this.addProperty("A", 1); + this.addProperty("B", 1); + this.addProperty("OP", "==", "enum", { values: GenericCompare.values }); + this.addWidget("combo","Op.",this.properties.OP,{ property: "OP", values: GenericCompare.values } ); + + this.size = [80, 60]; + } + + GenericCompare.values = ["==", "!="]; //[">", "<", "==", "!=", "<=", ">=", "||", "&&" ]; + GenericCompare["@OP"] = { + type: "enum", + title: "operation", + values: GenericCompare.values + }; + + GenericCompare.title = "Compare *"; + GenericCompare.desc = "evaluates condition between A and B"; + + GenericCompare.prototype.getTitle = function() { + return "*A " + this.properties.OP + " *B"; + }; + + GenericCompare.prototype.onExecute = function() { + var A = this.getInputData(0); + if (A === undefined) { + A = this.properties.A; + } else { + this.properties.A = A; + } + + var B = this.getInputData(1); + if (B === undefined) { + B = this.properties.B; + } else { + this.properties.B = B; + } + + var result = false; + if (typeof A == typeof B){ + switch (this.properties.OP) { + case "==": + case "!=": + // traverse both objects.. consider that this is not a true deep check! consider underscore or other library for thath :: _isEqual() + result = true; + switch(typeof A){ + case "object": + var aProps = Object.getOwnPropertyNames(A); + var bProps = Object.getOwnPropertyNames(B); + if (aProps.length != bProps.length){ + result = false; + break; + } + for (var i = 0; i < aProps.length; i++) { + var propName = aProps[i]; + if (A[propName] !== B[propName]) { + result = false; + break; + } + } + break; + default: + result = A == B; + } + if (this.properties.OP == "!=") result = !result; + break; + /*case ">": + result = A > B; + break; + case "<": + result = A < B; + break; + case "<=": + result = A <= B; + break; + case ">=": + result = A >= B; + break; + case "||": + result = A || B; + break; + case "&&": + result = A && B; + break;*/ + } + } + this.setOutputData(0, result); + this.setOutputData(1, !result); + }; + + LiteGraph.registerNodeType("basic/CompareValues", GenericCompare); + })(this); diff --git a/src/nodes/events.js b/src/nodes/events.js index af73fb591..3664fd62e 100644 --- a/src/nodes/events.js +++ b/src/nodes/events.js @@ -11,7 +11,7 @@ LogEvent.title = "Log Event"; LogEvent.desc = "Log event in console"; - LogEvent.prototype.onAction = function(action, param) { + LogEvent.prototype.onAction = function(action, param, options) { console.log(action, param); }; @@ -31,18 +31,18 @@ TriggerEvent.title = "TriggerEvent"; TriggerEvent.desc = "Triggers event if input evaluates to true"; - TriggerEvent.prototype.onExecute = function(action, param) { + TriggerEvent.prototype.onExecute = function( param, options) { var v = this.getInputData(0); var changed = (v != this.prev); if(this.prev === 0) changed = false; var must_resend = (changed && this.properties.only_on_change) || (!changed && !this.properties.only_on_change); if(v && must_resend ) - this.triggerSlot(0, param); + this.triggerSlot(0, param, null, options); if(!v && must_resend) - this.triggerSlot(2, param); + this.triggerSlot(2, param, null, options); if(changed) - this.triggerSlot(1, param); + this.triggerSlot(1, param, null, options); this.prev = v; }; @@ -50,7 +50,6 @@ //Sequencer for events function Sequencer() { - var that = this; this.addInput("", LiteGraph.ACTION); this.addInput("", LiteGraph.ACTION); this.addInput("", LiteGraph.ACTION); @@ -72,10 +71,13 @@ return ""; }; - Sequencer.prototype.onAction = function(action, param) { + Sequencer.prototype.onAction = function(action, param, options) { if (this.outputs) { + options = options || {}; for (var i = 0; i < this.outputs.length; ++i) { - this.triggerSlot(i, param); + // CREATE A NEW ID FOR THE ACTION + options.action_call = options.action_call?options.action_call+"_seq_"+i:this.id+"_"+(action?action:"action")+"_seq_"+i+"_"+Math.floor(Math.random()*9999); + this.triggerSlot(i, param, null, options); } } }; @@ -97,7 +99,7 @@ FilterEvent.title = "Filter Event"; FilterEvent.desc = "Blocks events that do not match the filter"; - FilterEvent.prototype.onAction = function(action, param) { + FilterEvent.prototype.onAction = function(action, param, options) { if (param == null) { return; } @@ -120,7 +122,7 @@ } } - this.triggerSlot(0, param); + this.triggerSlot(0, param, null, options); }; LiteGraph.registerNodeType("events/filter", FilterEvent); @@ -142,8 +144,9 @@ this._value = this.getInputData(1); } - EventBranch.prototype.onAction = function(action, param) { - this.triggerSlot(this._value ? 0 : 1); + EventBranch.prototype.onAction = function(action, param, options) { + this._value = this.getInputData(1); + this.triggerSlot(this._value ? 0 : 1, param, null, options); } LiteGraph.registerNodeType("events/branch", EventBranch); @@ -155,6 +158,8 @@ this.addInput("reset", LiteGraph.ACTION); this.addOutput("change", LiteGraph.EVENT); this.addOutput("num", "number"); + this.addProperty("doCountExecution", false, "boolean", {name: "Count Executions"}); + this.addWidget("toggle","Count Exec.",this.properties.doCountExecution,"doCountExecution"); this.num = 0; } @@ -168,7 +173,7 @@ return this.title; }; - EventCounter.prototype.onAction = function(action, param) { + EventCounter.prototype.onAction = function(action, param, options) { var v = this.num; if (action == "inc") { this.num += 1; @@ -193,6 +198,9 @@ }; EventCounter.prototype.onExecute = function() { + if(this.properties.doCountExecution){ + this.num += 1; + } this.setOutputData(1, this.num); }; @@ -211,16 +219,16 @@ DelayEvent.title = "Delay"; DelayEvent.desc = "Delays one event"; - DelayEvent.prototype.onAction = function(action, param) { + DelayEvent.prototype.onAction = function(action, param, options) { var time = this.properties.time_in_ms; if (time <= 0) { - this.trigger(null, param); + this.trigger(null, param, options); } else { this._pending.push([time, param]); } }; - DelayEvent.prototype.onExecute = function() { + DelayEvent.prototype.onExecute = function(param, options) { var dt = this.graph.elapsed_time * 1000; //in ms if (this.isInputConnected(1)) { @@ -228,9 +236,9 @@ } for (var i = 0; i < this._pending.length; ++i) { - var action = this._pending[i]; - action[0] -= dt; - if (action[0] > 0) { + var actionPass = this._pending[i]; + actionPass[0] -= dt; + if (actionPass[0] > 0) { continue; } @@ -239,7 +247,7 @@ --i; //trigger - this.trigger(null, action[1]); + this.trigger(null, actionPass[1], options); } }; @@ -359,9 +367,9 @@ function DataStore() { - this.addInput("data", ""); + this.addInput("data", 0); this.addInput("assign", LiteGraph.ACTION); - this.addOutput("data", ""); + this.addOutput("data", 0); this._last_value = null; this.properties = { data: null, serialize: true }; var that = this; @@ -379,7 +387,7 @@ this.setOutputData(0, this.properties.data ); } - DataStore.prototype.onAction = function(action, param) { + DataStore.prototype.onAction = function(action, param, options) { this.properties.data = this._last_value; }; diff --git a/src/nodes/interface.js b/src/nodes/interface.js index 41556429a..62cb51e82 100755 --- a/src/nodes/interface.js +++ b/src/nodes/interface.js @@ -71,6 +71,7 @@ local_pos[1] < this.size[1] - 2 ) { this.clicked = true; + this.setOutputData(1, this.clicked); this.triggerSlot(0, this.properties.message); return true; } @@ -672,7 +673,7 @@ typeof v == "number" ? v.toFixed(this.properties["decimals"]) : v; if (typeof this.str == "string") { - var lines = this.str.split("\\n"); + var lines = this.str.replace(/[\r\n]/g, "\\n").split("\\n"); for (var i=0; i < lines.length; i++) { ctx.fillText( lines[i], diff --git a/src/nodes/logic.js b/src/nodes/logic.js index e13c419ff..fe273dc3f 100755 --- a/src/nodes/logic.js +++ b/src/nodes/logic.js @@ -82,4 +82,120 @@ }; LiteGraph.registerNodeType("logic/sequence", Sequence); + + + function logicAnd(){ + this.properties = { }; + this.addInput("a", "boolean"); + this.addInput("b", "boolean"); + this.addOutput("out", "boolean"); + } + logicAnd.title = "AND"; + logicAnd.desc = "Return true if all inputs are true"; + logicAnd.prototype.onExecute = function() { + ret = true; + for (inX in this.inputs){ + if (!this.getInputData(inX)){ + ret = false; + break; + } + } + this.setOutputData(0, ret); + }; + logicAnd.prototype.onGetInputs = function() { + return [ + ["and", "boolean"] + ]; + }; + LiteGraph.registerNodeType("logic/AND", logicAnd); + + + function logicOr(){ + this.properties = { }; + this.addInput("a", "boolean"); + this.addInput("b", "boolean"); + this.addOutput("out", "boolean"); + } + logicOr.title = "OR"; + logicOr.desc = "Return true if at least one input is true"; + logicOr.prototype.onExecute = function() { + ret = false; + for (inX in this.inputs){ + if (this.getInputData(inX)){ + ret = true; + break; + } + } + this.setOutputData(0, ret); + }; + logicOr.prototype.onGetInputs = function() { + return [ + ["or", "boolean"] + ]; + }; + LiteGraph.registerNodeType("logic/OR", logicOr); + + + function logicNot(){ + this.properties = { }; + this.addInput("in", "boolean"); + this.addOutput("out", "boolean"); + } + logicNot.title = "NOT"; + logicNot.desc = "Return the logical negation"; + logicNot.prototype.onExecute = function() { + var ret = !this.getInputData(0); + this.setOutputData(0, ret); + }; + LiteGraph.registerNodeType("logic/NOT", logicNot); + + + function logicCompare(){ + this.properties = { }; + this.addInput("a", "boolean"); + this.addInput("b", "boolean"); + this.addOutput("out", "boolean"); + } + logicCompare.title = "bool == bool"; + logicCompare.desc = "Compare for logical equality"; + logicCompare.prototype.onExecute = function() { + last = null; + ret = true; + for (inX in this.inputs){ + if (last === null) last = this.getInputData(inX); + else + if (last != this.getInputData(inX)){ + ret = false; + break; + } + } + this.setOutputData(0, ret); + }; + logicCompare.prototype.onGetInputs = function() { + return [ + ["bool", "boolean"] + ]; + }; + LiteGraph.registerNodeType("logic/CompareBool", logicCompare); + + + function logicBranch(){ + this.properties = { }; + this.addInput("onTrigger", LiteGraph.ACTION); + this.addInput("condition", "boolean"); + this.addOutput("true", LiteGraph.EVENT); + this.addOutput("false", LiteGraph.EVENT); + this.mode = LiteGraph.ON_TRIGGER; + } + logicBranch.title = "Branch"; + logicBranch.desc = "Branch execution on condition"; + logicBranch.prototype.onExecute = function(param, options) { + var condtition = this.getInputData(1); + if (condtition){ + this.triggerSlot(0); + }else{ + this.triggerSlot(1); + } + }; + LiteGraph.registerNodeType("logic/IF", logicBranch); })(this); diff --git a/src/nodes/math.js b/src/nodes/math.js index 66fff8355..609eb3f6f 100755 --- a/src/nodes/math.js +++ b/src/nodes/math.js @@ -1,1329 +1,1329 @@ -(function(global) { - var LiteGraph = global.LiteGraph; - - //Converter - function Converter() { - this.addInput("in", ""); - this.addOutput("out"); - this.size = [80, 30]; - } - - Converter.title = "Converter"; - Converter.desc = "type A to type B"; - - Converter.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - - if (this.outputs) { - for (var i = 0; i < this.outputs.length; i++) { - var output = this.outputs[i]; - if (!output.links || !output.links.length) { - continue; - } - - var result = null; - switch (output.name) { - case "number": - result = v.length ? v[0] : parseFloat(v); - break; - case "vec2": - case "vec3": - case "vec4": - var result = null; - var count = 1; - switch (output.name) { - case "vec2": - count = 2; - break; - case "vec3": - count = 3; - break; - case "vec4": - count = 4; - break; - } - - var result = new Float32Array(count); - if (v.length) { - for ( - var j = 0; - j < v.length && j < result.length; - j++ - ) { - result[j] = v[j]; - } - } else { - result[0] = parseFloat(v); - } - break; - } - this.setOutputData(i, result); - } - } - }; - - Converter.prototype.onGetOutputs = function() { - return [ - ["number", "number"], - ["vec2", "vec2"], - ["vec3", "vec3"], - ["vec4", "vec4"] - ]; - }; - - LiteGraph.registerNodeType("math/converter", Converter); - - //Bypass - function Bypass() { - this.addInput("in"); - this.addOutput("out"); - this.size = [80, 30]; - } - - Bypass.title = "Bypass"; - Bypass.desc = "removes the type"; - - Bypass.prototype.onExecute = function() { - var v = this.getInputData(0); - this.setOutputData(0, v); - }; - - LiteGraph.registerNodeType("math/bypass", Bypass); - - function ToNumber() { - this.addInput("in"); - this.addOutput("out"); - } - - ToNumber.title = "to Number"; - ToNumber.desc = "Cast to number"; - - ToNumber.prototype.onExecute = function() { - var v = this.getInputData(0); - this.setOutputData(0, Number(v)); - }; - - LiteGraph.registerNodeType("math/to_number", ToNumber); - - function MathRange() { - this.addInput("in", "number", { locked: true }); - this.addOutput("out", "number", { locked: true }); - this.addOutput("clamped", "number", { locked: true }); - - this.addProperty("in", 0); - this.addProperty("in_min", 0); - this.addProperty("in_max", 1); - this.addProperty("out_min", 0); - this.addProperty("out_max", 1); - - this.size = [120, 50]; - } - - MathRange.title = "Range"; - MathRange.desc = "Convert a number from one range to another"; - - MathRange.prototype.getTitle = function() { - if (this.flags.collapsed) { - return (this._last_v || 0).toFixed(2); - } - return this.title; - }; - - MathRange.prototype.onExecute = function() { - if (this.inputs) { - for (var i = 0; i < this.inputs.length; i++) { - var input = this.inputs[i]; - var v = this.getInputData(i); - if (v === undefined) { - continue; - } - this.properties[input.name] = v; - } - } - - var v = this.properties["in"]; - if (v === undefined || v === null || v.constructor !== Number) { - v = 0; - } - - var in_min = this.properties.in_min; - var in_max = this.properties.in_max; - var out_min = this.properties.out_min; - var out_max = this.properties.out_max; - /* - if( in_min > in_max ) - { - in_min = in_max; - in_max = this.properties.in_min; - } - if( out_min > out_max ) - { - out_min = out_max; - out_max = this.properties.out_min; - } - */ - - this._last_v = ((v - in_min) / (in_max - in_min)) * (out_max - out_min) + out_min; - this.setOutputData(0, this._last_v); - this.setOutputData(1, Math.clamp( this._last_v, out_min, out_max )); - }; - - MathRange.prototype.onDrawBackground = function(ctx) { - //show the current value - if (this._last_v) { - this.outputs[0].label = this._last_v.toFixed(3); - } else { - this.outputs[0].label = "?"; - } - }; - - MathRange.prototype.onGetInputs = function() { - return [ - ["in_min", "number"], - ["in_max", "number"], - ["out_min", "number"], - ["out_max", "number"] - ]; - }; - - LiteGraph.registerNodeType("math/range", MathRange); - - function MathRand() { - this.addOutput("value", "number"); - this.addProperty("min", 0); - this.addProperty("max", 1); - this.size = [80, 30]; - } - - MathRand.title = "Rand"; - MathRand.desc = "Random number"; - - MathRand.prototype.onExecute = function() { - if (this.inputs) { - for (var i = 0; i < this.inputs.length; i++) { - var input = this.inputs[i]; - var v = this.getInputData(i); - if (v === undefined) { - continue; - } - this.properties[input.name] = v; - } - } - - var min = this.properties.min; - var max = this.properties.max; - this._last_v = Math.random() * (max - min) + min; - this.setOutputData(0, this._last_v); - }; - - MathRand.prototype.onDrawBackground = function(ctx) { - //show the current value - this.outputs[0].label = (this._last_v || 0).toFixed(3); - }; - - MathRand.prototype.onGetInputs = function() { - return [["min", "number"], ["max", "number"]]; - }; - - LiteGraph.registerNodeType("math/rand", MathRand); - - //basic continuous noise - function MathNoise() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.addProperty("min", 0); - this.addProperty("max", 1); - this.addProperty("smooth", true); - this.addProperty("seed", 0); - this.addProperty("octaves", 1); - this.addProperty("persistence", 0.8); - this.addProperty("speed", 1); - this.size = [90, 30]; - } - - MathNoise.title = "Noise"; - MathNoise.desc = "Random number with temporal continuity"; - MathNoise.data = null; - - MathNoise.getValue = function(f, smooth) { - if (!MathNoise.data) { - MathNoise.data = new Float32Array(1024); - for (var i = 0; i < MathNoise.data.length; ++i) { - MathNoise.data[i] = Math.random(); - } - } - f = f % 1024; - if (f < 0) { - f += 1024; - } - var f_min = Math.floor(f); - var f = f - f_min; - var r1 = MathNoise.data[f_min]; - var r2 = MathNoise.data[f_min == 1023 ? 0 : f_min + 1]; - if (smooth) { - f = f * f * f * (f * (f * 6.0 - 15.0) + 10.0); - } - return r1 * (1 - f) + r2 * f; - }; - - MathNoise.prototype.onExecute = function() { - var f = this.getInputData(0) || 0; - var iterations = this.properties.octaves || 1; - var r = 0; - var amp = 1; - var seed = this.properties.seed || 0; - f += seed; - var speed = this.properties.speed || 1; - var total_amp = 0; - for(var i = 0; i < iterations; ++i) - { - r += MathNoise.getValue(f * (1+i) * speed, this.properties.smooth) * amp; - total_amp += amp; - amp *= this.properties.persistence; - if(amp < 0.001) - break; - } - r /= total_amp; - var min = this.properties.min; - var max = this.properties.max; - this._last_v = r * (max - min) + min; - this.setOutputData(0, this._last_v); - }; - - MathNoise.prototype.onDrawBackground = function(ctx) { - //show the current value - this.outputs[0].label = (this._last_v || 0).toFixed(3); - }; - - LiteGraph.registerNodeType("math/noise", MathNoise); - - //generates spikes every random time - function MathSpikes() { - this.addOutput("out", "number"); - this.addProperty("min_time", 1); - this.addProperty("max_time", 2); - this.addProperty("duration", 0.2); - this.size = [90, 30]; - this._remaining_time = 0; - this._blink_time = 0; - } - - MathSpikes.title = "Spikes"; - MathSpikes.desc = "spike every random time"; - - MathSpikes.prototype.onExecute = function() { - var dt = this.graph.elapsed_time; //in secs - - this._remaining_time -= dt; - this._blink_time -= dt; - - var v = 0; - if (this._blink_time > 0) { - var f = this._blink_time / this.properties.duration; - v = 1 / (Math.pow(f * 8 - 4, 4) + 1); - } - - if (this._remaining_time < 0) { - this._remaining_time = - Math.random() * - (this.properties.max_time - this.properties.min_time) + - this.properties.min_time; - this._blink_time = this.properties.duration; - this.boxcolor = "#FFF"; - } else { - this.boxcolor = "#000"; - } - this.setOutputData(0, v); - }; - - LiteGraph.registerNodeType("math/spikes", MathSpikes); - - //Math clamp - function MathClamp() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.size = [80, 30]; - this.addProperty("min", 0); - this.addProperty("max", 1); - } - - MathClamp.title = "Clamp"; - MathClamp.desc = "Clamp number between min and max"; - //MathClamp.filter = "shader"; - - MathClamp.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - v = Math.max(this.properties.min, v); - v = Math.min(this.properties.max, v); - this.setOutputData(0, v); - }; - - MathClamp.prototype.getCode = function(lang) { - var code = ""; - if (this.isInputConnected(0)) { - code += - "clamp({{0}}," + - this.properties.min + - "," + - this.properties.max + - ")"; - } - return code; - }; - - LiteGraph.registerNodeType("math/clamp", MathClamp); - - //Math ABS - function MathLerp() { - this.properties = { f: 0.5 }; - this.addInput("A", "number"); - this.addInput("B", "number"); - - this.addOutput("out", "number"); - } - - MathLerp.title = "Lerp"; - MathLerp.desc = "Linear Interpolation"; - - MathLerp.prototype.onExecute = function() { - var v1 = this.getInputData(0); - if (v1 == null) { - v1 = 0; - } - var v2 = this.getInputData(1); - if (v2 == null) { - v2 = 0; - } - - var f = this.properties.f; - - var _f = this.getInputData(2); - if (_f !== undefined) { - f = _f; - } - - this.setOutputData(0, v1 * (1 - f) + v2 * f); - }; - - MathLerp.prototype.onGetInputs = function() { - return [["f", "number"]]; - }; - - LiteGraph.registerNodeType("math/lerp", MathLerp); - - //Math ABS - function MathAbs() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.size = [80, 30]; - } - - MathAbs.title = "Abs"; - MathAbs.desc = "Absolute"; - - MathAbs.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - this.setOutputData(0, Math.abs(v)); - }; - - LiteGraph.registerNodeType("math/abs", MathAbs); - - //Math Floor - function MathFloor() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.size = [80, 30]; - } - - MathFloor.title = "Floor"; - MathFloor.desc = "Floor number to remove fractional part"; - - MathFloor.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - this.setOutputData(0, Math.floor(v)); - }; - - LiteGraph.registerNodeType("math/floor", MathFloor); - - //Math frac - function MathFrac() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.size = [80, 30]; - } - - MathFrac.title = "Frac"; - MathFrac.desc = "Returns fractional part"; - - MathFrac.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - this.setOutputData(0, v % 1); - }; - - LiteGraph.registerNodeType("math/frac", MathFrac); - - //Math Floor - function MathSmoothStep() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.size = [80, 30]; - 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() { - this.addInput("in", "number", { label: "" }); - this.addOutput("out", "number", { label: "" }); - this.size = [80, 30]; - this.addProperty("factor", 1); - } - - MathScale.title = "Scale"; - MathScale.desc = "v * factor"; - - MathScale.prototype.onExecute = function() { - var value = this.getInputData(0); - if (value != null) { - this.setOutputData(0, value * this.properties.factor); - } - }; - - LiteGraph.registerNodeType("math/scale", MathScale); - - //Gate - function Gate() { - this.addInput("v","boolean"); - this.addInput("A"); - this.addInput("B"); - this.addOutput("out"); - } - - Gate.title = "Gate"; - Gate.desc = "if v is true, then outputs A, otherwise B"; - - Gate.prototype.onExecute = function() { - var v = this.getInputData(0); - this.setOutputData(0, this.getInputData( v ? 1 : 2 )); - }; - - LiteGraph.registerNodeType("math/gate", Gate); - - - //Math Average - function MathAverageFilter() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.size = [80, 30]; - this.addProperty("samples", 10); - this._values = new Float32Array(10); - this._current = 0; - } - - MathAverageFilter.title = "Average"; - MathAverageFilter.desc = "Average Filter"; - - MathAverageFilter.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - v = 0; - } - - var num_samples = this._values.length; - - this._values[this._current % num_samples] = v; - this._current += 1; - if (this._current > num_samples) { - this._current = 0; - } - - var avr = 0; - for (var i = 0; i < num_samples; ++i) { - avr += this._values[i]; - } - - this.setOutputData(0, avr / num_samples); - }; - - MathAverageFilter.prototype.onPropertyChanged = function(name, value) { - if (value < 1) { - value = 1; - } - this.properties.samples = Math.round(value); - var old = this._values; - - this._values = new Float32Array(this.properties.samples); - if (old.length <= this._values.length) { - this._values.set(old); - } else { - this._values.set(old.subarray(0, this._values.length)); - } - }; - - LiteGraph.registerNodeType("math/average", MathAverageFilter); - - //Math - function MathTendTo() { - this.addInput("in", "number"); - this.addOutput("out", "number"); - this.addProperty("factor", 0.1); - this.size = [80, 30]; - this._value = null; - } - - MathTendTo.title = "TendTo"; - MathTendTo.desc = "moves the output value always closer to the input"; - - MathTendTo.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - v = 0; - } - var f = this.properties.factor; - if (this._value == null) { - this._value = v; - } else { - this._value = this._value * (1 - f) + v * f; - } - this.setOutputData(0, this._value); - }; - - LiteGraph.registerNodeType("math/tendTo", MathTendTo); - - //Math operation - function MathOperation() { - this.addInput("A", "number,array,object"); - this.addInput("B", "number"); - this.addOutput("=", "number"); - this.addProperty("A", 1); - this.addProperty("B", 1); - this.addProperty("OP", "+", "enum", { values: MathOperation.values }); - this._func = function(A,B) { return A + B; }; - this._result = []; //only used for arrays - } - - MathOperation.values = ["+", "-", "*", "/", "%", "^", "max", "min"]; - - MathOperation.title = "Operation"; - MathOperation.desc = "Easy math operators"; - MathOperation["@OP"] = { - type: "enum", - title: "operation", - values: MathOperation.values - }; - MathOperation.size = [100, 60]; - - MathOperation.prototype.getTitle = function() { - if(this.properties.OP == "max" || this.properties.OP == "min") - return this.properties.OP + "(A,B)"; - return "A " + this.properties.OP + " B"; - }; - - MathOperation.prototype.setValue = function(v) { - if (typeof v == "string") { - v = parseFloat(v); - } - this.properties["value"] = v; - }; - - MathOperation.prototype.onPropertyChanged = function(name, value) - { - if (name != "OP") - return; - switch (this.properties.OP) { - case "+": this._func = function(A,B) { return A + B; }; break; - case "-": this._func = function(A,B) { return A - B; }; break; - case "x": - case "X": - case "*": this._func = function(A,B) { return A * B; }; break; - case "/": this._func = function(A,B) { return A / B; }; break; - case "%": this._func = function(A,B) { return A % B; }; break; - case "^": this._func = function(A,B) { return Math.pow(A, B); }; break; - case "max": this._func = function(A,B) { return Math.max(A, B); }; break; - case "min": this._func = function(A,B) { return Math.min(A, B); }; break; - default: - console.warn("Unknown operation: " + this.properties.OP); - this._func = function(A) { return A; }; - break; - } - } - - MathOperation.prototype.onExecute = function() { - var A = this.getInputData(0); - var B = this.getInputData(1); - if ( A != null ) { - if( A.constructor === Number ) - this.properties["A"] = A; - } else { - A = this.properties["A"]; - } - - if (B != null) { - this.properties["B"] = B; - } else { - B = this.properties["B"]; - } - - var result; - if(A.constructor === Number) - { - result = 0; - result = this._func(A,B); - } - else if(A.constructor === Array) - { - result = this._result; - result.length = A.length; - for(var i = 0; i < A.length; ++i) - result[i] = this._func(A[i],B); - } - else - { - result = {}; - for(var i in A) - result[i] = this._func(A[i],B); - } - this.setOutputData(0, result); - }; - - MathOperation.prototype.onDrawBackground = function(ctx) { - if (this.flags.collapsed) { - return; - } - - ctx.font = "40px Arial"; - ctx.fillStyle = "#666"; - ctx.textAlign = "center"; - ctx.fillText( - this.properties.OP, - this.size[0] * 0.5, - (this.size[1] + LiteGraph.NODE_TITLE_HEIGHT) * 0.5 - ); - ctx.textAlign = "left"; - }; - - LiteGraph.registerNodeType("math/operation", MathOperation); - - LiteGraph.registerSearchboxExtra("math/operation", "MAX", { - properties: {OP:"max"}, - title: "MAX()" - }); - - LiteGraph.registerSearchboxExtra("math/operation", "MIN", { - properties: {OP:"min"}, - title: "MIN()" - }); - - - //Math compare - function MathCompare() { - this.addInput("A", "number"); - this.addInput("B", "number"); - this.addOutput("A==B", "boolean"); - this.addOutput("A!=B", "boolean"); - this.addProperty("A", 0); - this.addProperty("B", 0); - } - - MathCompare.title = "Compare"; - MathCompare.desc = "compares between two values"; - - MathCompare.prototype.onExecute = function() { - var A = this.getInputData(0); - var B = this.getInputData(1); - if (A !== undefined) { - this.properties["A"] = A; - } else { - A = this.properties["A"]; - } - - if (B !== undefined) { - this.properties["B"] = B; - } else { - B = this.properties["B"]; - } - - for (var i = 0, l = this.outputs.length; i < l; ++i) { - var output = this.outputs[i]; - if (!output.links || !output.links.length) { - continue; - } - var value; - switch (output.name) { - case "A==B": - value = A == B; - break; - case "A!=B": - value = A != B; - break; - case "A>B": - value = A > B; - break; - case "A=B": - value = A >= B; - break; - } - this.setOutputData(i, value); - } - }; - - MathCompare.prototype.onGetOutputs = function() { - return [ - ["A==B", "boolean"], - ["A!=B", "boolean"], - ["A>B", "boolean"], - ["A=B", "boolean"], - ["A<=B", "boolean"] - ]; - }; - - LiteGraph.registerNodeType("math/compare", MathCompare); - - LiteGraph.registerSearchboxExtra("math/compare", "==", { - outputs: [["A==B", "boolean"]], - title: "A==B" - }); - LiteGraph.registerSearchboxExtra("math/compare", "!=", { - outputs: [["A!=B", "boolean"]], - title: "A!=B" - }); - LiteGraph.registerSearchboxExtra("math/compare", ">", { - outputs: [["A>B", "boolean"]], - title: "A>B" - }); - LiteGraph.registerSearchboxExtra("math/compare", "<", { - outputs: [["A=", { - outputs: [["A>=B", "boolean"]], - title: "A>=B" - }); - LiteGraph.registerSearchboxExtra("math/compare", "<=", { - outputs: [["A<=B", "boolean"]], - title: "A<=B" - }); - - function MathCondition() { - this.addInput("A", "number"); - this.addInput("B", "number"); - this.addOutput("true", "boolean"); - this.addOutput("false", "boolean"); - this.addProperty("A", 1); - this.addProperty("B", 1); - this.addProperty("OP", ">", "enum", { values: MathCondition.values }); - this.addWidget("combo","Cond.",this.properties.OP,{ property: "OP", values: MathCondition.values } ); - - this.size = [80, 60]; - } - - MathCondition.values = [">", "<", "==", "!=", "<=", ">=", "||", "&&" ]; - MathCondition["@OP"] = { - type: "enum", - title: "operation", - values: MathCondition.values - }; - - MathCondition.title = "Condition"; - MathCondition.desc = "evaluates condition between A and B"; - - MathCondition.prototype.getTitle = function() { - return "A " + this.properties.OP + " B"; - }; - - MathCondition.prototype.onExecute = function() { - var A = this.getInputData(0); - if (A === undefined) { - A = this.properties.A; - } else { - this.properties.A = A; - } - - var B = this.getInputData(1); - if (B === undefined) { - B = this.properties.B; - } else { - this.properties.B = B; - } - - var result = true; - switch (this.properties.OP) { - case ">": - result = A > B; - break; - case "<": - result = A < B; - break; - case "==": - result = A == B; - break; - case "!=": - result = A != B; - break; - case "<=": - result = A <= B; - break; - case ">=": - result = A >= B; - break; - case "||": - result = A || B; - break; - case "&&": - result = A && B; - break; - } - - this.setOutputData(0, result); - this.setOutputData(1, !result); - }; - - LiteGraph.registerNodeType("math/condition", MathCondition); - - - function MathBranch() { - this.addInput("in", ""); - this.addInput("cond", "boolean"); - this.addOutput("true", ""); - this.addOutput("false", ""); - this.size = [80, 60]; - } - - MathBranch.title = "Branch"; - MathBranch.desc = "If condition is true, outputs IN in true, otherwise in false"; - - MathBranch.prototype.onExecute = function() { - var V = this.getInputData(0); - var cond = this.getInputData(1); - - if(cond) - { - this.setOutputData(0, V); - this.setOutputData(1, null); - } - else - { - this.setOutputData(0, null); - this.setOutputData(1, V); - } - } - - LiteGraph.registerNodeType("math/branch", MathBranch); - - - function MathAccumulate() { - this.addInput("inc", "number"); - this.addOutput("total", "number"); - this.addProperty("increment", 1); - this.addProperty("value", 0); - } - - MathAccumulate.title = "Accumulate"; - MathAccumulate.desc = "Increments a value every time"; - - MathAccumulate.prototype.onExecute = function() { - if (this.properties.value === null) { - this.properties.value = 0; - } - - var inc = this.getInputData(0); - if (inc !== null) { - this.properties.value += inc; - } else { - this.properties.value += this.properties.increment; - } - this.setOutputData(0, this.properties.value); - }; - - LiteGraph.registerNodeType("math/accumulate", MathAccumulate); - - //Math Trigonometry - function MathTrigonometry() { - this.addInput("v", "number"); - this.addOutput("sin", "number"); - - this.addProperty("amplitude", 1); - this.addProperty("offset", 0); - this.bgImageUrl = "nodes/imgs/icon-sin.png"; - } - - MathTrigonometry.title = "Trigonometry"; - MathTrigonometry.desc = "Sin Cos Tan"; - //MathTrigonometry.filter = "shader"; - - MathTrigonometry.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - v = 0; - } - var amplitude = this.properties["amplitude"]; - var slot = this.findInputSlot("amplitude"); - if (slot != -1) { - amplitude = this.getInputData(slot); - } - var offset = this.properties["offset"]; - slot = this.findInputSlot("offset"); - if (slot != -1) { - offset = this.getInputData(slot); - } - - for (var i = 0, l = this.outputs.length; i < l; ++i) { - var output = this.outputs[i]; - var value; - switch (output.name) { - case "sin": - value = Math.sin(v); - break; - case "cos": - value = Math.cos(v); - break; - case "tan": - value = Math.tan(v); - break; - case "asin": - value = Math.asin(v); - break; - case "acos": - value = Math.acos(v); - break; - case "atan": - value = Math.atan(v); - break; - } - this.setOutputData(i, amplitude * value + offset); - } - }; - - MathTrigonometry.prototype.onGetInputs = function() { - return [["v", "number"], ["amplitude", "number"], ["offset", "number"]]; - }; - - MathTrigonometry.prototype.onGetOutputs = function() { - return [ - ["sin", "number"], - ["cos", "number"], - ["tan", "number"], - ["asin", "number"], - ["acos", "number"], - ["atan", "number"] - ]; - }; - - LiteGraph.registerNodeType("math/trigonometry", MathTrigonometry); - - LiteGraph.registerSearchboxExtra("math/trigonometry", "SIN()", { - outputs: [["sin", "number"]], - title: "SIN()" - }); - LiteGraph.registerSearchboxExtra("math/trigonometry", "COS()", { - outputs: [["cos", "number"]], - title: "COS()" - }); - LiteGraph.registerSearchboxExtra("math/trigonometry", "TAN()", { - outputs: [["tan", "number"]], - title: "TAN()" - }); - - //math library for safe math operations without eval - function MathFormula() { - this.addInput("x", "number"); - this.addInput("y", "number"); - this.addOutput("", "number"); - this.properties = { x: 1.0, y: 1.0, formula: "x+y" }; - this.code_widget = this.addWidget( - "text", - "F(x,y)", - this.properties.formula, - function(v, canvas, node) { - node.properties.formula = v; - } - ); - this.addWidget("toggle", "allow", LiteGraph.allow_scripts, function(v) { - LiteGraph.allow_scripts = v; - }); - this._func = null; - } - - MathFormula.title = "Formula"; - MathFormula.desc = "Compute formula"; - MathFormula.size = [160, 100]; - - MathAverageFilter.prototype.onPropertyChanged = function(name, value) { - if (name == "formula") { - this.code_widget.value = value; - } - }; - - MathFormula.prototype.onExecute = function() { - if (!LiteGraph.allow_scripts) { - return; - } - - var x = this.getInputData(0); - var y = this.getInputData(1); - if (x != null) { - this.properties["x"] = x; - } else { - x = this.properties["x"]; - } - - if (y != null) { - this.properties["y"] = y; - } else { - y = this.properties["y"]; - } - - var f = this.properties["formula"]; - - var value; - try { - if (!this._func || this._func_code != this.properties.formula) { - this._func = new Function( - "x", - "y", - "TIME", - "return " + this.properties.formula - ); - this._func_code = this.properties.formula; - } - value = this._func(x, y, this.graph.globaltime); - this.boxcolor = null; - } catch (err) { - this.boxcolor = "red"; - } - this.setOutputData(0, value); - }; - - MathFormula.prototype.getTitle = function() { - return this._func_code || "Formula"; - }; - - MathFormula.prototype.onDrawBackground = function() { - var f = this.properties["formula"]; - if (this.outputs && this.outputs.length) { - this.outputs[0].label = f; - } - }; - - LiteGraph.registerNodeType("math/formula", MathFormula); - - function Math3DVec2ToXY() { - this.addInput("vec2", "vec2"); - this.addOutput("x", "number"); - this.addOutput("y", "number"); - } - - Math3DVec2ToXY.title = "Vec2->XY"; - Math3DVec2ToXY.desc = "vector 2 to components"; - - Math3DVec2ToXY.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - - this.setOutputData(0, v[0]); - this.setOutputData(1, v[1]); - }; - - LiteGraph.registerNodeType("math3d/vec2-to-xy", Math3DVec2ToXY); - - function Math3DXYToVec2() { - this.addInputs([["x", "number"], ["y", "number"]]); - this.addOutput("vec2", "vec2"); - this.properties = { x: 0, y: 0 }; - this._data = new Float32Array(2); - } - - Math3DXYToVec2.title = "XY->Vec2"; - Math3DXYToVec2.desc = "components to vector2"; - - Math3DXYToVec2.prototype.onExecute = function() { - var x = this.getInputData(0); - if (x == null) { - x = this.properties.x; - } - var y = this.getInputData(1); - if (y == null) { - y = this.properties.y; - } - - var data = this._data; - data[0] = x; - data[1] = y; - - this.setOutputData(0, data); - }; - - LiteGraph.registerNodeType("math3d/xy-to-vec2", Math3DXYToVec2); - - function Math3DVec3ToXYZ() { - this.addInput("vec3", "vec3"); - this.addOutput("x", "number"); - this.addOutput("y", "number"); - this.addOutput("z", "number"); - } - - Math3DVec3ToXYZ.title = "Vec3->XYZ"; - Math3DVec3ToXYZ.desc = "vector 3 to components"; - - Math3DVec3ToXYZ.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - - this.setOutputData(0, v[0]); - this.setOutputData(1, v[1]); - this.setOutputData(2, v[2]); - }; - - LiteGraph.registerNodeType("math3d/vec3-to-xyz", Math3DVec3ToXYZ); - - function Math3DXYZToVec3() { - this.addInputs([["x", "number"], ["y", "number"], ["z", "number"]]); - this.addOutput("vec3", "vec3"); - this.properties = { x: 0, y: 0, z: 0 }; - this._data = new Float32Array(3); - } - - Math3DXYZToVec3.title = "XYZ->Vec3"; - Math3DXYZToVec3.desc = "components to vector3"; - - Math3DXYZToVec3.prototype.onExecute = function() { - var x = this.getInputData(0); - if (x == null) { - x = this.properties.x; - } - var y = this.getInputData(1); - if (y == null) { - y = this.properties.y; - } - var z = this.getInputData(2); - if (z == null) { - z = this.properties.z; - } - - var data = this._data; - data[0] = x; - data[1] = y; - data[2] = z; - - this.setOutputData(0, data); - }; - - LiteGraph.registerNodeType("math3d/xyz-to-vec3", Math3DXYZToVec3); - - function Math3DVec4ToXYZW() { - this.addInput("vec4", "vec4"); - this.addOutput("x", "number"); - this.addOutput("y", "number"); - this.addOutput("z", "number"); - this.addOutput("w", "number"); - } - - Math3DVec4ToXYZW.title = "Vec4->XYZW"; - Math3DVec4ToXYZW.desc = "vector 4 to components"; - - Math3DVec4ToXYZW.prototype.onExecute = function() { - var v = this.getInputData(0); - if (v == null) { - return; - } - - this.setOutputData(0, v[0]); - this.setOutputData(1, v[1]); - this.setOutputData(2, v[2]); - this.setOutputData(3, v[3]); - }; - - LiteGraph.registerNodeType("math3d/vec4-to-xyzw", Math3DVec4ToXYZW); - - function Math3DXYZWToVec4() { - this.addInputs([ - ["x", "number"], - ["y", "number"], - ["z", "number"], - ["w", "number"] - ]); - this.addOutput("vec4", "vec4"); - this.properties = { x: 0, y: 0, z: 0, w: 0 }; - this._data = new Float32Array(4); - } - - Math3DXYZWToVec4.title = "XYZW->Vec4"; - Math3DXYZWToVec4.desc = "components to vector4"; - - Math3DXYZWToVec4.prototype.onExecute = function() { - var x = this.getInputData(0); - if (x == null) { - x = this.properties.x; - } - var y = this.getInputData(1); - if (y == null) { - y = this.properties.y; - } - var z = this.getInputData(2); - if (z == null) { - z = this.properties.z; - } - var w = this.getInputData(3); - if (w == null) { - w = this.properties.w; - } - - var data = this._data; - data[0] = x; - data[1] = y; - data[2] = z; - data[3] = w; - - this.setOutputData(0, data); - }; - - LiteGraph.registerNodeType("math3d/xyzw-to-vec4", Math3DXYZWToVec4); - -})(this); +(function(global) { + var LiteGraph = global.LiteGraph; + + //Converter + function Converter() { + this.addInput("in", 0); + this.addOutput("out", 0); + this.size = [80, 30]; + } + + Converter.title = "Converter"; + Converter.desc = "type A to type B"; + + Converter.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + + if (this.outputs) { + for (var i = 0; i < this.outputs.length; i++) { + var output = this.outputs[i]; + if (!output.links || !output.links.length) { + continue; + } + + var result = null; + switch (output.name) { + case "number": + result = v.length ? v[0] : parseFloat(v); + break; + case "vec2": + case "vec3": + case "vec4": + var result = null; + var count = 1; + switch (output.name) { + case "vec2": + count = 2; + break; + case "vec3": + count = 3; + break; + case "vec4": + count = 4; + break; + } + + var result = new Float32Array(count); + if (v.length) { + for ( + var j = 0; + j < v.length && j < result.length; + j++ + ) { + result[j] = v[j]; + } + } else { + result[0] = parseFloat(v); + } + break; + } + this.setOutputData(i, result); + } + } + }; + + Converter.prototype.onGetOutputs = function() { + return [ + ["number", "number"], + ["vec2", "vec2"], + ["vec3", "vec3"], + ["vec4", "vec4"] + ]; + }; + + LiteGraph.registerNodeType("math/converter", Converter); + + //Bypass + function Bypass() { + this.addInput("in"); + this.addOutput("out"); + this.size = [80, 30]; + } + + Bypass.title = "Bypass"; + Bypass.desc = "removes the type"; + + Bypass.prototype.onExecute = function() { + var v = this.getInputData(0); + this.setOutputData(0, v); + }; + + LiteGraph.registerNodeType("math/bypass", Bypass); + + function ToNumber() { + this.addInput("in"); + this.addOutput("out"); + } + + ToNumber.title = "to Number"; + ToNumber.desc = "Cast to number"; + + ToNumber.prototype.onExecute = function() { + var v = this.getInputData(0); + this.setOutputData(0, Number(v)); + }; + + LiteGraph.registerNodeType("math/to_number", ToNumber); + + function MathRange() { + this.addInput("in", "number", { locked: true }); + this.addOutput("out", "number", { locked: true }); + this.addOutput("clamped", "number", { locked: true }); + + this.addProperty("in", 0); + this.addProperty("in_min", 0); + this.addProperty("in_max", 1); + this.addProperty("out_min", 0); + this.addProperty("out_max", 1); + + this.size = [120, 50]; + } + + MathRange.title = "Range"; + MathRange.desc = "Convert a number from one range to another"; + + MathRange.prototype.getTitle = function() { + if (this.flags.collapsed) { + return (this._last_v || 0).toFixed(2); + } + return this.title; + }; + + MathRange.prototype.onExecute = function() { + if (this.inputs) { + for (var i = 0; i < this.inputs.length; i++) { + var input = this.inputs[i]; + var v = this.getInputData(i); + if (v === undefined) { + continue; + } + this.properties[input.name] = v; + } + } + + var v = this.properties["in"]; + if (v === undefined || v === null || v.constructor !== Number) { + v = 0; + } + + var in_min = this.properties.in_min; + var in_max = this.properties.in_max; + var out_min = this.properties.out_min; + var out_max = this.properties.out_max; + /* + if( in_min > in_max ) + { + in_min = in_max; + in_max = this.properties.in_min; + } + if( out_min > out_max ) + { + out_min = out_max; + out_max = this.properties.out_min; + } + */ + + this._last_v = ((v - in_min) / (in_max - in_min)) * (out_max - out_min) + out_min; + this.setOutputData(0, this._last_v); + this.setOutputData(1, Math.clamp( this._last_v, out_min, out_max )); + }; + + MathRange.prototype.onDrawBackground = function(ctx) { + //show the current value + if (this._last_v) { + this.outputs[0].label = this._last_v.toFixed(3); + } else { + this.outputs[0].label = "?"; + } + }; + + MathRange.prototype.onGetInputs = function() { + return [ + ["in_min", "number"], + ["in_max", "number"], + ["out_min", "number"], + ["out_max", "number"] + ]; + }; + + LiteGraph.registerNodeType("math/range", MathRange); + + function MathRand() { + this.addOutput("value", "number"); + this.addProperty("min", 0); + this.addProperty("max", 1); + this.size = [80, 30]; + } + + MathRand.title = "Rand"; + MathRand.desc = "Random number"; + + MathRand.prototype.onExecute = function() { + if (this.inputs) { + for (var i = 0; i < this.inputs.length; i++) { + var input = this.inputs[i]; + var v = this.getInputData(i); + if (v === undefined) { + continue; + } + this.properties[input.name] = v; + } + } + + var min = this.properties.min; + var max = this.properties.max; + this._last_v = Math.random() * (max - min) + min; + this.setOutputData(0, this._last_v); + }; + + MathRand.prototype.onDrawBackground = function(ctx) { + //show the current value + this.outputs[0].label = (this._last_v || 0).toFixed(3); + }; + + MathRand.prototype.onGetInputs = function() { + return [["min", "number"], ["max", "number"]]; + }; + + LiteGraph.registerNodeType("math/rand", MathRand); + + //basic continuous noise + function MathNoise() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.addProperty("min", 0); + this.addProperty("max", 1); + this.addProperty("smooth", true); + this.addProperty("seed", 0); + this.addProperty("octaves", 1); + this.addProperty("persistence", 0.8); + this.addProperty("speed", 1); + this.size = [90, 30]; + } + + MathNoise.title = "Noise"; + MathNoise.desc = "Random number with temporal continuity"; + MathNoise.data = null; + + MathNoise.getValue = function(f, smooth) { + if (!MathNoise.data) { + MathNoise.data = new Float32Array(1024); + for (var i = 0; i < MathNoise.data.length; ++i) { + MathNoise.data[i] = Math.random(); + } + } + f = f % 1024; + if (f < 0) { + f += 1024; + } + var f_min = Math.floor(f); + var f = f - f_min; + var r1 = MathNoise.data[f_min]; + var r2 = MathNoise.data[f_min == 1023 ? 0 : f_min + 1]; + if (smooth) { + f = f * f * f * (f * (f * 6.0 - 15.0) + 10.0); + } + return r1 * (1 - f) + r2 * f; + }; + + MathNoise.prototype.onExecute = function() { + var f = this.getInputData(0) || 0; + var iterations = this.properties.octaves || 1; + var r = 0; + var amp = 1; + var seed = this.properties.seed || 0; + f += seed; + var speed = this.properties.speed || 1; + var total_amp = 0; + for(var i = 0; i < iterations; ++i) + { + r += MathNoise.getValue(f * (1+i) * speed, this.properties.smooth) * amp; + total_amp += amp; + amp *= this.properties.persistence; + if(amp < 0.001) + break; + } + r /= total_amp; + var min = this.properties.min; + var max = this.properties.max; + this._last_v = r * (max - min) + min; + this.setOutputData(0, this._last_v); + }; + + MathNoise.prototype.onDrawBackground = function(ctx) { + //show the current value + this.outputs[0].label = (this._last_v || 0).toFixed(3); + }; + + LiteGraph.registerNodeType("math/noise", MathNoise); + + //generates spikes every random time + function MathSpikes() { + this.addOutput("out", "number"); + this.addProperty("min_time", 1); + this.addProperty("max_time", 2); + this.addProperty("duration", 0.2); + this.size = [90, 30]; + this._remaining_time = 0; + this._blink_time = 0; + } + + MathSpikes.title = "Spikes"; + MathSpikes.desc = "spike every random time"; + + MathSpikes.prototype.onExecute = function() { + var dt = this.graph.elapsed_time; //in secs + + this._remaining_time -= dt; + this._blink_time -= dt; + + var v = 0; + if (this._blink_time > 0) { + var f = this._blink_time / this.properties.duration; + v = 1 / (Math.pow(f * 8 - 4, 4) + 1); + } + + if (this._remaining_time < 0) { + this._remaining_time = + Math.random() * + (this.properties.max_time - this.properties.min_time) + + this.properties.min_time; + this._blink_time = this.properties.duration; + this.boxcolor = "#FFF"; + } else { + this.boxcolor = "#000"; + } + this.setOutputData(0, v); + }; + + LiteGraph.registerNodeType("math/spikes", MathSpikes); + + //Math clamp + function MathClamp() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.size = [80, 30]; + this.addProperty("min", 0); + this.addProperty("max", 1); + } + + MathClamp.title = "Clamp"; + MathClamp.desc = "Clamp number between min and max"; + //MathClamp.filter = "shader"; + + MathClamp.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + v = Math.max(this.properties.min, v); + v = Math.min(this.properties.max, v); + this.setOutputData(0, v); + }; + + MathClamp.prototype.getCode = function(lang) { + var code = ""; + if (this.isInputConnected(0)) { + code += + "clamp({{0}}," + + this.properties.min + + "," + + this.properties.max + + ")"; + } + return code; + }; + + LiteGraph.registerNodeType("math/clamp", MathClamp); + + //Math ABS + function MathLerp() { + this.properties = { f: 0.5 }; + this.addInput("A", "number"); + this.addInput("B", "number"); + + this.addOutput("out", "number"); + } + + MathLerp.title = "Lerp"; + MathLerp.desc = "Linear Interpolation"; + + MathLerp.prototype.onExecute = function() { + var v1 = this.getInputData(0); + if (v1 == null) { + v1 = 0; + } + var v2 = this.getInputData(1); + if (v2 == null) { + v2 = 0; + } + + var f = this.properties.f; + + var _f = this.getInputData(2); + if (_f !== undefined) { + f = _f; + } + + this.setOutputData(0, v1 * (1 - f) + v2 * f); + }; + + MathLerp.prototype.onGetInputs = function() { + return [["f", "number"]]; + }; + + LiteGraph.registerNodeType("math/lerp", MathLerp); + + //Math ABS + function MathAbs() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.size = [80, 30]; + } + + MathAbs.title = "Abs"; + MathAbs.desc = "Absolute"; + + MathAbs.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + this.setOutputData(0, Math.abs(v)); + }; + + LiteGraph.registerNodeType("math/abs", MathAbs); + + //Math Floor + function MathFloor() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.size = [80, 30]; + } + + MathFloor.title = "Floor"; + MathFloor.desc = "Floor number to remove fractional part"; + + MathFloor.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + this.setOutputData(0, Math.floor(v)); + }; + + LiteGraph.registerNodeType("math/floor", MathFloor); + + //Math frac + function MathFrac() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.size = [80, 30]; + } + + MathFrac.title = "Frac"; + MathFrac.desc = "Returns fractional part"; + + MathFrac.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + this.setOutputData(0, v % 1); + }; + + LiteGraph.registerNodeType("math/frac", MathFrac); + + //Math Floor + function MathSmoothStep() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.size = [80, 30]; + 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() { + this.addInput("in", "number", { label: "" }); + this.addOutput("out", "number", { label: "" }); + this.size = [80, 30]; + this.addProperty("factor", 1); + } + + MathScale.title = "Scale"; + MathScale.desc = "v * factor"; + + MathScale.prototype.onExecute = function() { + var value = this.getInputData(0); + if (value != null) { + this.setOutputData(0, value * this.properties.factor); + } + }; + + LiteGraph.registerNodeType("math/scale", MathScale); + + //Gate + function Gate() { + this.addInput("v","boolean"); + this.addInput("A"); + this.addInput("B"); + this.addOutput("out"); + } + + Gate.title = "Gate"; + Gate.desc = "if v is true, then outputs A, otherwise B"; + + Gate.prototype.onExecute = function() { + var v = this.getInputData(0); + this.setOutputData(0, this.getInputData( v ? 1 : 2 )); + }; + + LiteGraph.registerNodeType("math/gate", Gate); + + + //Math Average + function MathAverageFilter() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.size = [80, 30]; + this.addProperty("samples", 10); + this._values = new Float32Array(10); + this._current = 0; + } + + MathAverageFilter.title = "Average"; + MathAverageFilter.desc = "Average Filter"; + + MathAverageFilter.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + v = 0; + } + + var num_samples = this._values.length; + + this._values[this._current % num_samples] = v; + this._current += 1; + if (this._current > num_samples) { + this._current = 0; + } + + var avr = 0; + for (var i = 0; i < num_samples; ++i) { + avr += this._values[i]; + } + + this.setOutputData(0, avr / num_samples); + }; + + MathAverageFilter.prototype.onPropertyChanged = function(name, value) { + if (value < 1) { + value = 1; + } + this.properties.samples = Math.round(value); + var old = this._values; + + this._values = new Float32Array(this.properties.samples); + if (old.length <= this._values.length) { + this._values.set(old); + } else { + this._values.set(old.subarray(0, this._values.length)); + } + }; + + LiteGraph.registerNodeType("math/average", MathAverageFilter); + + //Math + function MathTendTo() { + this.addInput("in", "number"); + this.addOutput("out", "number"); + this.addProperty("factor", 0.1); + this.size = [80, 30]; + this._value = null; + } + + MathTendTo.title = "TendTo"; + MathTendTo.desc = "moves the output value always closer to the input"; + + MathTendTo.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + v = 0; + } + var f = this.properties.factor; + if (this._value == null) { + this._value = v; + } else { + this._value = this._value * (1 - f) + v * f; + } + this.setOutputData(0, this._value); + }; + + LiteGraph.registerNodeType("math/tendTo", MathTendTo); + + //Math operation + function MathOperation() { + this.addInput("A", "number,array,object"); + this.addInput("B", "number"); + this.addOutput("=", "number"); + this.addProperty("A", 1); + this.addProperty("B", 1); + this.addProperty("OP", "+", "enum", { values: MathOperation.values }); + this._func = function(A,B) { return A + B; }; + this._result = []; //only used for arrays + } + + MathOperation.values = ["+", "-", "*", "/", "%", "^", "max", "min"]; + + MathOperation.title = "Operation"; + MathOperation.desc = "Easy math operators"; + MathOperation["@OP"] = { + type: "enum", + title: "operation", + values: MathOperation.values + }; + MathOperation.size = [100, 60]; + + MathOperation.prototype.getTitle = function() { + if(this.properties.OP == "max" || this.properties.OP == "min") + return this.properties.OP + "(A,B)"; + return "A " + this.properties.OP + " B"; + }; + + MathOperation.prototype.setValue = function(v) { + if (typeof v == "string") { + v = parseFloat(v); + } + this.properties["value"] = v; + }; + + MathOperation.prototype.onPropertyChanged = function(name, value) + { + if (name != "OP") + return; + switch (this.properties.OP) { + case "+": this._func = function(A,B) { return A + B; }; break; + case "-": this._func = function(A,B) { return A - B; }; break; + case "x": + case "X": + case "*": this._func = function(A,B) { return A * B; }; break; + case "/": this._func = function(A,B) { return A / B; }; break; + case "%": this._func = function(A,B) { return A % B; }; break; + case "^": this._func = function(A,B) { return Math.pow(A, B); }; break; + case "max": this._func = function(A,B) { return Math.max(A, B); }; break; + case "min": this._func = function(A,B) { return Math.min(A, B); }; break; + default: + console.warn("Unknown operation: " + this.properties.OP); + this._func = function(A) { return A; }; + break; + } + } + + MathOperation.prototype.onExecute = function() { + var A = this.getInputData(0); + var B = this.getInputData(1); + if ( A != null ) { + if( A.constructor === Number ) + this.properties["A"] = A; + } else { + A = this.properties["A"]; + } + + if (B != null) { + this.properties["B"] = B; + } else { + B = this.properties["B"]; + } + + var result; + if(A.constructor === Number) + { + result = 0; + result = this._func(A,B); + } + else if(A.constructor === Array) + { + result = this._result; + result.length = A.length; + for(var i = 0; i < A.length; ++i) + result[i] = this._func(A[i],B); + } + else + { + result = {}; + for(var i in A) + result[i] = this._func(A[i],B); + } + this.setOutputData(0, result); + }; + + MathOperation.prototype.onDrawBackground = function(ctx) { + if (this.flags.collapsed) { + return; + } + + ctx.font = "40px Arial"; + ctx.fillStyle = "#666"; + ctx.textAlign = "center"; + ctx.fillText( + this.properties.OP, + this.size[0] * 0.5, + (this.size[1] + LiteGraph.NODE_TITLE_HEIGHT) * 0.5 + ); + ctx.textAlign = "left"; + }; + + LiteGraph.registerNodeType("math/operation", MathOperation); + + LiteGraph.registerSearchboxExtra("math/operation", "MAX", { + properties: {OP:"max"}, + title: "MAX()" + }); + + LiteGraph.registerSearchboxExtra("math/operation", "MIN", { + properties: {OP:"min"}, + title: "MIN()" + }); + + + //Math compare + function MathCompare() { + this.addInput("A", "number"); + this.addInput("B", "number"); + this.addOutput("A==B", "boolean"); + this.addOutput("A!=B", "boolean"); + this.addProperty("A", 0); + this.addProperty("B", 0); + } + + MathCompare.title = "Compare"; + MathCompare.desc = "compares between two values"; + + MathCompare.prototype.onExecute = function() { + var A = this.getInputData(0); + var B = this.getInputData(1); + if (A !== undefined) { + this.properties["A"] = A; + } else { + A = this.properties["A"]; + } + + if (B !== undefined) { + this.properties["B"] = B; + } else { + B = this.properties["B"]; + } + + for (var i = 0, l = this.outputs.length; i < l; ++i) { + var output = this.outputs[i]; + if (!output.links || !output.links.length) { + continue; + } + var value; + switch (output.name) { + case "A==B": + value = A == B; + break; + case "A!=B": + value = A != B; + break; + case "A>B": + value = A > B; + break; + case "A=B": + value = A >= B; + break; + } + this.setOutputData(i, value); + } + }; + + MathCompare.prototype.onGetOutputs = function() { + return [ + ["A==B", "boolean"], + ["A!=B", "boolean"], + ["A>B", "boolean"], + ["A=B", "boolean"], + ["A<=B", "boolean"] + ]; + }; + + LiteGraph.registerNodeType("math/compare", MathCompare); + + LiteGraph.registerSearchboxExtra("math/compare", "==", { + outputs: [["A==B", "boolean"]], + title: "A==B" + }); + LiteGraph.registerSearchboxExtra("math/compare", "!=", { + outputs: [["A!=B", "boolean"]], + title: "A!=B" + }); + LiteGraph.registerSearchboxExtra("math/compare", ">", { + outputs: [["A>B", "boolean"]], + title: "A>B" + }); + LiteGraph.registerSearchboxExtra("math/compare", "<", { + outputs: [["A=", { + outputs: [["A>=B", "boolean"]], + title: "A>=B" + }); + LiteGraph.registerSearchboxExtra("math/compare", "<=", { + outputs: [["A<=B", "boolean"]], + title: "A<=B" + }); + + function MathCondition() { + this.addInput("A", "number"); + this.addInput("B", "number"); + this.addOutput("true", "boolean"); + this.addOutput("false", "boolean"); + this.addProperty("A", 1); + this.addProperty("B", 1); + this.addProperty("OP", ">", "enum", { values: MathCondition.values }); + this.addWidget("combo","Cond.",this.properties.OP,{ property: "OP", values: MathCondition.values } ); + + this.size = [80, 60]; + } + + MathCondition.values = [">", "<", "==", "!=", "<=", ">=", "||", "&&" ]; + MathCondition["@OP"] = { + type: "enum", + title: "operation", + values: MathCondition.values + }; + + MathCondition.title = "Condition"; + MathCondition.desc = "evaluates condition between A and B"; + + MathCondition.prototype.getTitle = function() { + return "A " + this.properties.OP + " B"; + }; + + MathCondition.prototype.onExecute = function() { + var A = this.getInputData(0); + if (A === undefined) { + A = this.properties.A; + } else { + this.properties.A = A; + } + + var B = this.getInputData(1); + if (B === undefined) { + B = this.properties.B; + } else { + this.properties.B = B; + } + + var result = true; + switch (this.properties.OP) { + case ">": + result = A > B; + break; + case "<": + result = A < B; + break; + case "==": + result = A == B; + break; + case "!=": + result = A != B; + break; + case "<=": + result = A <= B; + break; + case ">=": + result = A >= B; + break; + case "||": + result = A || B; + break; + case "&&": + result = A && B; + break; + } + + this.setOutputData(0, result); + this.setOutputData(1, !result); + }; + + LiteGraph.registerNodeType("math/condition", MathCondition); + + + function MathBranch() { + this.addInput("in", 0); + this.addInput("cond", "boolean"); + this.addOutput("true", 0); + this.addOutput("false", 0); + this.size = [80, 60]; + } + + MathBranch.title = "Branch"; + MathBranch.desc = "If condition is true, outputs IN in true, otherwise in false"; + + MathBranch.prototype.onExecute = function() { + var V = this.getInputData(0); + var cond = this.getInputData(1); + + if(cond) + { + this.setOutputData(0, V); + this.setOutputData(1, null); + } + else + { + this.setOutputData(0, null); + this.setOutputData(1, V); + } + } + + LiteGraph.registerNodeType("math/branch", MathBranch); + + + function MathAccumulate() { + this.addInput("inc", "number"); + this.addOutput("total", "number"); + this.addProperty("increment", 1); + this.addProperty("value", 0); + } + + MathAccumulate.title = "Accumulate"; + MathAccumulate.desc = "Increments a value every time"; + + MathAccumulate.prototype.onExecute = function() { + if (this.properties.value === null) { + this.properties.value = 0; + } + + var inc = this.getInputData(0); + if (inc !== null) { + this.properties.value += inc; + } else { + this.properties.value += this.properties.increment; + } + this.setOutputData(0, this.properties.value); + }; + + LiteGraph.registerNodeType("math/accumulate", MathAccumulate); + + //Math Trigonometry + function MathTrigonometry() { + this.addInput("v", "number"); + this.addOutput("sin", "number"); + + this.addProperty("amplitude", 1); + this.addProperty("offset", 0); + this.bgImageUrl = "nodes/imgs/icon-sin.png"; + } + + MathTrigonometry.title = "Trigonometry"; + MathTrigonometry.desc = "Sin Cos Tan"; + //MathTrigonometry.filter = "shader"; + + MathTrigonometry.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + v = 0; + } + var amplitude = this.properties["amplitude"]; + var slot = this.findInputSlot("amplitude"); + if (slot != -1) { + amplitude = this.getInputData(slot); + } + var offset = this.properties["offset"]; + slot = this.findInputSlot("offset"); + if (slot != -1) { + offset = this.getInputData(slot); + } + + for (var i = 0, l = this.outputs.length; i < l; ++i) { + var output = this.outputs[i]; + var value; + switch (output.name) { + case "sin": + value = Math.sin(v); + break; + case "cos": + value = Math.cos(v); + break; + case "tan": + value = Math.tan(v); + break; + case "asin": + value = Math.asin(v); + break; + case "acos": + value = Math.acos(v); + break; + case "atan": + value = Math.atan(v); + break; + } + this.setOutputData(i, amplitude * value + offset); + } + }; + + MathTrigonometry.prototype.onGetInputs = function() { + return [["v", "number"], ["amplitude", "number"], ["offset", "number"]]; + }; + + MathTrigonometry.prototype.onGetOutputs = function() { + return [ + ["sin", "number"], + ["cos", "number"], + ["tan", "number"], + ["asin", "number"], + ["acos", "number"], + ["atan", "number"] + ]; + }; + + LiteGraph.registerNodeType("math/trigonometry", MathTrigonometry); + + LiteGraph.registerSearchboxExtra("math/trigonometry", "SIN()", { + outputs: [["sin", "number"]], + title: "SIN()" + }); + LiteGraph.registerSearchboxExtra("math/trigonometry", "COS()", { + outputs: [["cos", "number"]], + title: "COS()" + }); + LiteGraph.registerSearchboxExtra("math/trigonometry", "TAN()", { + outputs: [["tan", "number"]], + title: "TAN()" + }); + + //math library for safe math operations without eval + function MathFormula() { + this.addInput("x", "number"); + this.addInput("y", "number"); + this.addOutput("", "number"); + this.properties = { x: 1.0, y: 1.0, formula: "x+y" }; + this.code_widget = this.addWidget( + "text", + "F(x,y)", + this.properties.formula, + function(v, canvas, node) { + node.properties.formula = v; + } + ); + this.addWidget("toggle", "allow", LiteGraph.allow_scripts, function(v) { + LiteGraph.allow_scripts = v; + }); + this._func = null; + } + + MathFormula.title = "Formula"; + MathFormula.desc = "Compute formula"; + MathFormula.size = [160, 100]; + + MathAverageFilter.prototype.onPropertyChanged = function(name, value) { + if (name == "formula") { + this.code_widget.value = value; + } + }; + + MathFormula.prototype.onExecute = function() { + if (!LiteGraph.allow_scripts) { + return; + } + + var x = this.getInputData(0); + var y = this.getInputData(1); + if (x != null) { + this.properties["x"] = x; + } else { + x = this.properties["x"]; + } + + if (y != null) { + this.properties["y"] = y; + } else { + y = this.properties["y"]; + } + + var f = this.properties["formula"]; + + var value; + try { + if (!this._func || this._func_code != this.properties.formula) { + this._func = new Function( + "x", + "y", + "TIME", + "return " + this.properties.formula + ); + this._func_code = this.properties.formula; + } + value = this._func(x, y, this.graph.globaltime); + this.boxcolor = null; + } catch (err) { + this.boxcolor = "red"; + } + this.setOutputData(0, value); + }; + + MathFormula.prototype.getTitle = function() { + return this._func_code || "Formula"; + }; + + MathFormula.prototype.onDrawBackground = function() { + var f = this.properties["formula"]; + if (this.outputs && this.outputs.length) { + this.outputs[0].label = f; + } + }; + + LiteGraph.registerNodeType("math/formula", MathFormula); + + function Math3DVec2ToXY() { + this.addInput("vec2", "vec2"); + this.addOutput("x", "number"); + this.addOutput("y", "number"); + } + + Math3DVec2ToXY.title = "Vec2->XY"; + Math3DVec2ToXY.desc = "vector 2 to components"; + + Math3DVec2ToXY.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + + this.setOutputData(0, v[0]); + this.setOutputData(1, v[1]); + }; + + LiteGraph.registerNodeType("math3d/vec2-to-xy", Math3DVec2ToXY); + + function Math3DXYToVec2() { + this.addInputs([["x", "number"], ["y", "number"]]); + this.addOutput("vec2", "vec2"); + this.properties = { x: 0, y: 0 }; + this._data = new Float32Array(2); + } + + Math3DXYToVec2.title = "XY->Vec2"; + Math3DXYToVec2.desc = "components to vector2"; + + Math3DXYToVec2.prototype.onExecute = function() { + var x = this.getInputData(0); + if (x == null) { + x = this.properties.x; + } + var y = this.getInputData(1); + if (y == null) { + y = this.properties.y; + } + + var data = this._data; + data[0] = x; + data[1] = y; + + this.setOutputData(0, data); + }; + + LiteGraph.registerNodeType("math3d/xy-to-vec2", Math3DXYToVec2); + + function Math3DVec3ToXYZ() { + this.addInput("vec3", "vec3"); + this.addOutput("x", "number"); + this.addOutput("y", "number"); + this.addOutput("z", "number"); + } + + Math3DVec3ToXYZ.title = "Vec3->XYZ"; + Math3DVec3ToXYZ.desc = "vector 3 to components"; + + Math3DVec3ToXYZ.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + + this.setOutputData(0, v[0]); + this.setOutputData(1, v[1]); + this.setOutputData(2, v[2]); + }; + + LiteGraph.registerNodeType("math3d/vec3-to-xyz", Math3DVec3ToXYZ); + + function Math3DXYZToVec3() { + this.addInputs([["x", "number"], ["y", "number"], ["z", "number"]]); + this.addOutput("vec3", "vec3"); + this.properties = { x: 0, y: 0, z: 0 }; + this._data = new Float32Array(3); + } + + Math3DXYZToVec3.title = "XYZ->Vec3"; + Math3DXYZToVec3.desc = "components to vector3"; + + Math3DXYZToVec3.prototype.onExecute = function() { + var x = this.getInputData(0); + if (x == null) { + x = this.properties.x; + } + var y = this.getInputData(1); + if (y == null) { + y = this.properties.y; + } + var z = this.getInputData(2); + if (z == null) { + z = this.properties.z; + } + + var data = this._data; + data[0] = x; + data[1] = y; + data[2] = z; + + this.setOutputData(0, data); + }; + + LiteGraph.registerNodeType("math3d/xyz-to-vec3", Math3DXYZToVec3); + + function Math3DVec4ToXYZW() { + this.addInput("vec4", "vec4"); + this.addOutput("x", "number"); + this.addOutput("y", "number"); + this.addOutput("z", "number"); + this.addOutput("w", "number"); + } + + Math3DVec4ToXYZW.title = "Vec4->XYZW"; + Math3DVec4ToXYZW.desc = "vector 4 to components"; + + Math3DVec4ToXYZW.prototype.onExecute = function() { + var v = this.getInputData(0); + if (v == null) { + return; + } + + this.setOutputData(0, v[0]); + this.setOutputData(1, v[1]); + this.setOutputData(2, v[2]); + this.setOutputData(3, v[3]); + }; + + LiteGraph.registerNodeType("math3d/vec4-to-xyzw", Math3DVec4ToXYZW); + + function Math3DXYZWToVec4() { + this.addInputs([ + ["x", "number"], + ["y", "number"], + ["z", "number"], + ["w", "number"] + ]); + this.addOutput("vec4", "vec4"); + this.properties = { x: 0, y: 0, z: 0, w: 0 }; + this._data = new Float32Array(4); + } + + Math3DXYZWToVec4.title = "XYZW->Vec4"; + Math3DXYZWToVec4.desc = "components to vector4"; + + Math3DXYZWToVec4.prototype.onExecute = function() { + var x = this.getInputData(0); + if (x == null) { + x = this.properties.x; + } + var y = this.getInputData(1); + if (y == null) { + y = this.properties.y; + } + var z = this.getInputData(2); + if (z == null) { + z = this.properties.z; + } + var w = this.getInputData(3); + if (w == null) { + w = this.properties.w; + } + + var data = this._data; + data[0] = x; + data[1] = y; + data[2] = z; + data[3] = w; + + this.setOutputData(0, data); + }; + + LiteGraph.registerNodeType("math3d/xyzw-to-vec4", Math3DXYZWToVec4); + +})(this); diff --git a/src/nodes/others.js b/src/nodes/others.js index e69de29bb..7d720af64 100755 --- a/src/nodes/others.js +++ b/src/nodes/others.js @@ -0,0 +1 @@ +// extra generic nodes \ No newline at end of file diff --git a/src/nodes/strings.js b/src/nodes/strings.js index c39173465..88f641d91 100644 --- a/src/nodes/strings.js +++ b/src/nodes/strings.js @@ -17,7 +17,7 @@ return String(a); } - LiteGraph.wrapFunctionAsNode("string/toString", toString, [""], "String"); + LiteGraph.wrapFunctionAsNode("string/toString", toString, [""], "string"); function compare(a, b) { return a == b; @@ -85,8 +85,10 @@ else if( str.constructor === Array ) { var r = []; - for(var i = 0; i < str.length; ++i) - r[i] = str[i].split(separator || " "); + for(var i = 0; i < str.length; ++i){ + if (typeof str[i] == "string") + r[i] = str[i].split(separator || " "); + } return r; } return null;