variable class works better\nFixes in panels\nBetter shader generation.

This commit is contained in:
tamat
2020-07-17 19:21:07 +02:00
parent d40ad5a0d5
commit c74d8760b1
7 changed files with 1089 additions and 643 deletions

View File

@@ -5,3 +5,5 @@ There are some simple rules that everyone should follow:
> I usually have horrible merge conflicts when I upload the build version that take me too much time to solve, but I want to keep the build version in the repo, so I guess it would be better if only one of us does the built, which would be me.
> https://github.com/jagenjo/litegraph.js/pull/155#issuecomment-656602861
Those files will be updated by owner.

View File

@@ -4,7 +4,7 @@ A library in Javascript to create graphs in the browser similar to Unreal Bluepr
It can be integrated easily in any existing web applications and graphs can be run without the need of the editor.
Try it in the [demo site](https://tamats.com/projects/litegraph/demo).
Try it in the [demo site](https://tamats.com/projects/litegraph/editor).
![Node Graph](imgs/node_graph_example.png "WebGLStudio")

View File

@@ -55,7 +55,6 @@
CIRCLE_SHAPE: 3,
CARD_SHAPE: 4,
ARROW_SHAPE: 5,
SQUARE_SHAPE: 6,
//enums
INPUT: 1,
@@ -94,19 +93,10 @@
registered_node_types: {}, //nodetypes by string
node_types_by_file_extension: {}, //used for dropping files in the canvas
Nodes: {}, //node types by classname
Globals: {}, //used to store vars between graphs
searchbox_extras: {}, //used to add extra features to the search box
/**
* Removes all previously registered node's types
*/
clearRegisteredTypes: function() {
this.registered_node_types = {};
this.node_types_by_file_extension = {};
this.Nodes = {};
this.searchbox_extras = {};
},
/**
* Register a node class so it can be listed when the user wants to create a new one
* @method registerNodeType
@@ -1591,8 +1581,10 @@
return;
}
node.graph.beforeChange();
this.inputs[name] = { name: name, type: type, value: value };
this._version++;
node.graph.afterChange();
if (this.onInputAdded) {
this.onInputAdded(name, type);
@@ -1853,6 +1845,22 @@
}
};
//used for undo, called before any change is made to the graph
LGraph.prototype.beforeChange = function(info) {
if (this.onBeforeChange) {
this.onBeforeChange(this,info);
}
this.sendActionToCanvas("onBeforeChange", this);
};
//used to resend actions, called after any change is made to the graph
LGraph.prototype.afterChange = function(info) {
if (this.onAfterChange) {
this.onAfterChange(this,info);
}
this.sendActionToCanvas("onAfterChange", this);
};
LGraph.prototype.connectionChange = function(node, link_info) {
this.updateExecutionOrder();
if (this.onConnectionChange) {
@@ -3136,6 +3144,7 @@
if (!this.inputs) {
this.inputs = [];
}
this.inputs.push(o);
this.setSize( this.computeSize() );
@@ -3223,10 +3232,10 @@
/**
* computes the minimum size of a node according to its inputs and output slots
* @method computeSize
* @param {number} the optional target width
* @param {number} minHeight
* @return {number} the total size
*/
LGraphNode.prototype.computeSize = function(width, out) {
LGraphNode.prototype.computeSize = function(out) {
if (this.constructor.size) {
return this.constructor.size.concat();
}
@@ -3278,7 +3287,7 @@
if (this.widgets && this.widgets.length) {
for (var i = 0, l = this.widgets.length; i < l; ++i) {
if (this.widgets[i].computeSize)
widgets_height += this.widgets[i].computeSize(Math.max(size[0], width || 0))[1] + 4;
widgets_height += this.widgets[i].computeSize(size[0])[1] + 4;
else
widgets_height += LiteGraph.NODE_WIDGET_HEIGHT + 4;
}
@@ -3337,8 +3346,11 @@
if(this.constructor["@" + property])
info = this.constructor["@" + property];
if(this.constructor.widgets_info && this.constructor.widgets_info[property])
info = this.constructor.widgets_info[property];
//litescene mode using the constructor
if (this.onGetPropertyInfo) {
if (!info && this.onGetPropertyInfo) {
info = this.onGetPropertyInfo(property);
}
@@ -3346,6 +3358,8 @@
info = {};
if(!info.type)
info.type = typeof this.properties[property];
if(info.widget == "combo")
info.type = "enum";
return info;
}
@@ -3644,25 +3658,21 @@
return null;
}
var output = this.outputs[slot];
var input = target_node.inputs[target_slot];
if (LiteGraph.isValidConnection(output.type, input.type)) {
if (target_node.onBeforeConnectInput) {
// This way node can choose another slot (if selected is occupied)
target_slot = target_node.onBeforeConnectInput(target_slot);
input = target_node.inputs[target_slot];
}
var changed = false;
//if there is something already plugged there, disconnect
if (target_node.inputs[target_slot].link != null) {
this.graph.beforeChange();
target_node.disconnectInput(target_slot);
changed = true;
}
//why here??
//this.setDirtyCanvas(false,true);
//this.graph.connectionChange( this );
var output = this.outputs[slot];
//allows nodes to block connection
if (target_node.onConnectInput) {
if ( target_node.onConnectInput(target_slot, output.type, output, this, slot) === false ) {
@@ -3670,8 +3680,22 @@
}
}
var input = target_node.inputs[target_slot];
var link_info = null;
//this slots cannot be connected (different types)
if (!LiteGraph.isValidConnection(output.type, input.type))
{
this.setDirtyCanvas(false, true);
if(changed)
this.graph.connectionChange(this, link_info);
return null;
}
if(!changed)
this.graph.beforeChange();
//create link class
link_info = new LLink(
++this.graph.last_link_id,
input.type,
@@ -3728,9 +3752,9 @@
target_slot
);
}
}
this.setDirtyCanvas(false, true);
this.graph.afterChange();
this.graph.connectionChange(this, link_info);
return link_info;
@@ -4566,8 +4590,7 @@ LGraphNode.prototype.executeAction = function(action)
//if(graph === undefined)
// throw ("No graph assigned");
this.background_image =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII=";
this.background_image = LGraphCanvas.DEFAULT_BACKGROUND_IMAGE;
if (canvas && canvas.constructor === String) {
canvas = document.querySelector(canvas);
@@ -4640,6 +4663,9 @@ LGraphNode.prototype.executeAction = function(action)
this.onDrawLinkTooltip = null; //called when rendering a tooltip
this.onNodeMoved = null; //called after moving a node
this.onSelectionChange = null; //called if the selection changes
this.onConnectingChange = null; //called before any link changes
this.onBeforeChange = null; //called before modifying the graph
this.onAfterChange = null; //called after modifying the graph
this.connections_width = 3;
this.round_radius = 8;
@@ -4668,6 +4694,8 @@ LGraphNode.prototype.executeAction = function(action)
global.LGraphCanvas = LiteGraph.LGraphCanvas = LGraphCanvas;
LGraphCanvas.DEFAULT_BACKGROUND_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII=";
LGraphCanvas.link_type_colors = {
"-1": LiteGraph.EVENT_LINK_COLOR,
number: "#AAA",
@@ -5171,15 +5199,17 @@ LGraphNode.prototype.executeAction = function(action)
LiteGraph.closeAllContextMenus(ref_window);
if (this.onMouse) {
if (this.onMouse(e) == true) {
if (this.onMouse)
{
if (this.onMouse(e) == true)
return;
}
}
if (e.which == 1) {
//left button mouse
if (e.ctrlKey) {
if (e.which == 1)
{
if (e.ctrlKey)
{
this.dragging_rectangle = new Float32Array(4);
this.dragging_rectangle[0] = e.canvasX;
this.dragging_rectangle[1] = e.canvasY;
@@ -5216,6 +5246,7 @@ LGraphNode.prototype.executeAction = function(action)
10
)
) {
this.graph.beforeChange();
this.resizing_node = node;
this.canvas.style.cursor = "se-resize";
skip_action = true;
@@ -5323,15 +5354,6 @@ LGraphNode.prototype.executeAction = function(action)
} //not resizing
}
//Search for corner for collapsing
/*
if( !skip_action && isInsideRectangle( e.canvasX, e.canvasY, node.pos[0], node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT ))
{
node.collapse();
skip_action = true;
}
*/
//it wasn't clicked on the links boxes
if (!skip_action) {
var block_drag_node = false;
@@ -5377,6 +5399,7 @@ LGraphNode.prototype.executeAction = function(action)
if (!block_drag_node) {
if (this.allow_dragnodes) {
this.graph.beforeChange();
this.node_dragged = node;
}
if (!this.selected_nodes[node.id]) {
@@ -5684,7 +5707,7 @@ LGraphNode.prototype.executeAction = function(action)
if (this.resizing_node && !this.live_mode) {
//convert mouse to node space
var desired_size = [ e.canvasX - this.resizing_node.pos[0], e.canvasY - this.resizing_node.pos[1] ];
var min_size = this.resizing_node.computeSize(desired_size[0]);
var min_size = this.resizing_node.computeSize();
desired_size[0] = Math.max( min_size[0], desired_size[0] );
desired_size[1] = Math.max( min_size[1], desired_size[1] );
this.resizing_node.setSize( desired_size );
@@ -5876,6 +5899,7 @@ LGraphNode.prototype.executeAction = function(action)
else if (this.resizing_node) {
this.dirty_canvas = true;
this.dirty_bgcanvas = true;
this.graph.afterChange(this.resizing_node);
this.resizing_node = null;
} else if (this.node_dragged) {
//node being dragged?
@@ -5897,6 +5921,7 @@ LGraphNode.prototype.executeAction = function(action)
}
if( this.onNodeMoved )
this.onNodeMoved( this.node_dragged );
this.graph.afterChange(this.node_dragged);
this.node_dragged = null;
} //no node being dragged
else {
@@ -6196,6 +6221,8 @@ LGraphNode.prototype.executeAction = function(action)
return;
}
this.graph.beforeChange();
//create nodes
var clipboard_info = JSON.parse(data);
var nodes = [];
@@ -6223,6 +6250,8 @@ LGraphNode.prototype.executeAction = function(action)
}
this.selectNodes(nodes);
this.graph.afterChange();
};
/**
@@ -6303,12 +6332,14 @@ LGraphNode.prototype.executeAction = function(action)
var ext = LGraphCanvas.getFileExtension(file.name).toLowerCase();
var nodetype = LiteGraph.node_types_by_file_extension[ext];
if (nodetype) {
this.graph.beforeChange();
var node = LiteGraph.createNode(nodetype.type);
node.pos = [e.canvasX, e.canvasY];
this.graph.add(node);
if (node.onDropFile) {
node.onDropFile(file);
}
this.graph.afterChange();
}
}
};
@@ -6467,6 +6498,9 @@ LGraphNode.prototype.executeAction = function(action)
* @method deleteSelectedNodes
**/
LGraphCanvas.prototype.deleteSelectedNodes = function() {
this.graph.beforeChange();
for (var i in this.selected_nodes) {
var node = this.selected_nodes[i];
@@ -6492,6 +6526,7 @@ LGraphNode.prototype.executeAction = function(action)
this.current_node = null;
this.highlighted_links = {};
this.setDirty(true);
this.graph.afterChange();
};
/**
@@ -6946,6 +6981,7 @@ LGraphNode.prototype.executeAction = function(action)
if( this.drawButton( 20,y+2,w - 20, h - 2 ) )
{
var type = subnode.constructor.input_node_type || "graph/input";
this.graph.beforeChange();
var newnode = LiteGraph.createNode( type );
if(newnode)
{
@@ -6959,6 +6995,7 @@ LGraphNode.prototype.executeAction = function(action)
newnode.setProperty("type",input.type);
this.node_dragged.pos[0] = this.graph_mouse[0] - 5;
this.node_dragged.pos[1] = this.graph_mouse[1] - 5;
this.graph.afterChange();
}
else
console.error("graph input node not found:",type);
@@ -7231,44 +7268,6 @@ LGraphNode.prototype.executeAction = function(action)
var temp_vec2 = new Float32Array(2);
LGraphCanvas.prototype.drawSlotGraphic = function(ctx, pos, shape, horizontal) {
ctx.beginPath();
switch (shape) {
case (LiteGraph.BOX_SHAPE):
if (horizontal) {
ctx.rect(
pos[0] - 5 + 0.5,
pos[1] - 8 + 0.5,
10,
14
);
} else {
ctx.rect(
pos[0] - 6 + 0.5,
pos[1] - 5 + 0.5,
14,
10
);
}
break;
case (LiteGraph.ARROW_SHAPE):
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
ctx.closePath();
break;
case (LiteGraph.SQUARE_SHAPE):
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8); //faster
break;
case (LiteGraph.CIRCLE_SHAPE):
default:
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
break;
}
ctx.fill();
}
/**
* draws the given node inside the canvas
* @method drawNode
@@ -7418,9 +7417,39 @@ LGraphNode.prototype.executeAction = function(action)
max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5;
}
var shape = slot.shape || (slot.type === LiteGraph.EVENT && LiteGraph.BOX_SHAPE)
|| (low_quality && LiteGraph.SQUARE_SHAPE) || LiteGraph.CIRCLE_SHAPE;
this.drawSlotGraphic(ctx, pos, shape, horizontal);
ctx.beginPath();
if (
slot.type === LiteGraph.EVENT ||
slot.shape === LiteGraph.BOX_SHAPE
) {
if (horizontal) {
ctx.rect(
pos[0] - 5 + 0.5,
pos[1] - 8 + 0.5,
10,
14
);
} else {
ctx.rect(
pos[0] - 6 + 0.5,
pos[1] - 5 + 0.5,
14,
10
);
}
} else if (slot.shape === LiteGraph.ARROW_SHAPE) {
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
ctx.closePath();
} else {
if(low_quality)
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 ); //faster
else
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
}
ctx.fill();
//render name
if (render_text) {
@@ -7461,11 +7490,46 @@ LGraphNode.prototype.executeAction = function(action)
this.default_connection_color.output_on
: slot.color_off ||
this.default_connection_color.output_off;
ctx.beginPath();
//ctx.rect( node.size[0] - 14,i*14,10,10);
var shape = slot.shape || (slot.type === LiteGraph.EVENT && LiteGraph.BOX_SHAPE)
|| (low_quality && LiteGraph.SQUARE_SHAPE) || LiteGraph.CIRCLE_SHAPE;
this.drawSlotGraphic(ctx, pos, shape, horizontal);
if (
slot.type === LiteGraph.EVENT ||
slot.shape === LiteGraph.BOX_SHAPE
) {
if (horizontal) {
ctx.rect(
pos[0] - 5 + 0.5,
pos[1] - 8 + 0.5,
10,
14
);
} else {
ctx.rect(
pos[0] - 6 + 0.5,
pos[1] - 5 + 0.5,
14,
10
);
}
} else if (slot.shape === LiteGraph.ARROW_SHAPE) {
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
ctx.closePath();
} else {
if(low_quality)
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 );
else
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
}
//trigger
//if(slot.node_id != null && slot.slot == -1)
// ctx.fillStyle = "#F85";
//if(slot.links != null && slot.links.length)
ctx.fill();
if(!low_quality)
ctx.stroke();
@@ -8706,7 +8770,14 @@ LGraphNode.prototype.executeAction = function(action)
if(!w || w.disabled)
continue;
var widget_height = w.computeSize ? w.computeSize(width)[1] : LiteGraph.NODE_WIDGET_HEIGHT;
if ( w == active_widget || (x > 6 && x < width - 12 && y > w.last_y && y < w.last_y + widget_height) ) {
//outside
if ( w != active_widget &&
(x < 6 || x > width - 12 || y < w.last_y || y > w.last_y + widget_height) )
continue;
var old_value = w.value;
//if ( w == active_widget || (x > 6 && x < width - 12 && y > w.last_y && y < w.last_y + widget_height) ) {
//inside widget
switch (w.type) {
case "button":
@@ -8846,9 +8917,14 @@ LGraphNode.prototype.executeAction = function(action)
break;
} //end switch
//value changed
if( old_value != w.value )
{
node.graph._version++;
}
return w;
}
}
}//end for
function inner_value_change(widget, value) {
widget.value = value;
@@ -9079,6 +9155,7 @@ LGraphNode.prototype.executeAction = function(action)
function inner_create(v, e) {
var first_event = prev_menu.getFirstEvent();
canvas.graph.beforeChange();
var node = LiteGraph.createNode(v.value);
if (node) {
node.pos = canvas.convertEventToCanvasOffset(first_event);
@@ -9086,6 +9163,7 @@ LGraphNode.prototype.executeAction = function(action)
}
if(callback)
callback(node);
canvas.graph.afterChange();
}
return false;
@@ -9165,8 +9243,10 @@ LGraphNode.prototype.executeAction = function(action)
}
if (v.value) {
node.graph.beforeChange();
node.addInput(v.value[0], v.value[1], v.value[2]);
node.setDirtyCanvas(true, true);
node.graph.afterChange();
}
}
@@ -9273,8 +9353,10 @@ LGraphNode.prototype.executeAction = function(action)
});
return false;
} else {
node.graph.beforeChange();
node.addOutput(v.value[0], v.value[1], v.value[2]);
node.setDirtyCanvas(true, true);
node.graph.afterChange();
}
}
@@ -9301,6 +9383,10 @@ LGraphNode.prototype.executeAction = function(action)
var value = node.properties[i] !== undefined ? node.properties[i] : " ";
if( typeof value == "object" )
value = JSON.stringify(value);
var info = node.getPropertyInfo(i);
if(info.type == "enum" || info.type == "combo")
value = LGraphCanvas.getPropertyPrintableValue( value, info.values );
//value could contain invalid html characters, clean that
value = LGraphCanvas.decodeHTML(value);
entries.push({
@@ -9703,6 +9789,7 @@ LGraphNode.prototype.executeAction = function(action)
name = extra.type;
}
graphcanvas.graph.beforeChange();
var node = LiteGraph.createNode(name);
if (node) {
node.pos = graphcanvas.convertEventToCanvasOffset(
@@ -9741,6 +9828,8 @@ LGraphNode.prototype.executeAction = function(action)
if (extra.data.json) {
node.configure(extra.data.json);
}
graphcanvas.graph.afterChange();
}
}
}
@@ -9872,10 +9961,13 @@ LGraphNode.prototype.executeAction = function(action)
if (type == "string" || type == "number" || type == "array" || type == "object") {
input_html = "<input autofocus type='text' class='value'/>";
} else if (type == "enum" && info.values) {
} else if ( (type == "enum" || type == "combo") && info.values) {
input_html = "<select autofocus type='text' class='value'>";
for (var i in info.values) {
var v = info.values.constructor === Array ? info.values[i] : i;
var v = i;
if( info.values.constructor === Array )
v = info.values[i];
input_html +=
"<option value='" +
v +
@@ -9905,7 +9997,7 @@ LGraphNode.prototype.executeAction = function(action)
options
);
if (type == "enum" && info.values) {
if ((type == "enum" || type == "combo") && info.values) {
var input = dialog.querySelector("select");
input.addEventListener("change", function(e) {
setValue(e.target.value);
@@ -9947,6 +10039,10 @@ LGraphNode.prototype.executeAction = function(action)
}
function setValue(value) {
if(info && info.values && info.values.constructor === Object && info.values[value] != undefined )
value = info.values[value];
if (typeof node.properties[property] == "number") {
value = Number(value);
}
@@ -9954,8 +10050,8 @@ LGraphNode.prototype.executeAction = function(action)
value = JSON.parse(value);
}
node.properties[property] = value;
if (node._graph) {
node._graph._version++;
if (node.graph) {
node.graph._version++;
}
if (node.onPropertyChanged) {
node.onPropertyChanged(property, value);
@@ -10133,7 +10229,10 @@ LGraphNode.prototype.executeAction = function(action)
innerChange(propname, v);
});
}
else if (type == "enum")
else if (type == "enum" || type == "combo")
var str_value = LGraphCanvas.getPropertyPrintableValue( value, options.values );
value_element.innerText = str_value;
value_element.addEventListener("click", function(event){
var values = options.values || [];
var propname = this.parentNode.dataset["property"];
@@ -10171,6 +10270,30 @@ LGraphNode.prototype.executeAction = function(action)
return root;
};
LGraphCanvas.getPropertyPrintableValue = function(value, values)
{
if(!values)
return String(value);
if(values.constructor === Array)
{
return String(value);
}
if(values.constructor === Object)
{
var desc_value = "";
for(var k in values)
{
if(values[k] != value)
continue;
desc_value = k;
break;
}
return String(value) + " ("+desc_value+")";
}
}
LGraphCanvas.prototype.showShowNodePanel = function( node )
{
window.SELECTED_NODE = node;
@@ -10203,7 +10326,9 @@ LGraphNode.prototype.executeAction = function(action)
continue;
panel.addWidget( info.widget || info.type, i, value, info, function(name,value){
graphcanvas.graph.beforeChange(node);
node.setProperty(name,value);
graphcanvas.graph.afterChange();
graphcanvas.dirty_canvas = true;
});
}
@@ -10348,7 +10473,9 @@ LGraphNode.prototype.executeAction = function(action)
}
LGraphCanvas.onMenuNodeCollapse = function(value, options, e, menu, node) {
node.graph.beforeChange(node);
node.collapse();
node.graph.afterChange(node);
};
LGraphCanvas.onMenuNodePin = function(value, options, e, menu, node) {
@@ -10458,7 +10585,9 @@ LGraphNode.prototype.executeAction = function(action)
if (!node) {
return;
}
node.graph.beforeChange(node);
node.shape = v;
node.graph.afterChange(node);
node.setDirtyCanvas(true);
}
@@ -10474,7 +10603,10 @@ LGraphNode.prototype.executeAction = function(action)
return;
}
node.graph.remove(node);
var graph = node.graph;
graph.beforeChange();
graph.remove(node);
graph.afterChange();
node.setDirtyCanvas(true, true);
};
@@ -10507,7 +10639,11 @@ LGraphNode.prototype.executeAction = function(action)
return;
}
newnode.pos = [node.pos[0] + 5, node.pos[1] + 5];
node.graph.beforeChange();
node.graph.add(newnode);
node.graph.afterChange();
node.setDirtyCanvas(true, true);
};
@@ -12695,22 +12831,52 @@ if (typeof exports != "undefined") {
this.size = [60, 30];
this.addInput("in");
this.addOutput("out");
this.properties = { varname: "myname", global: false };
this.properties = { varname: "myname", container: Variable.LITEGRAPH };
this.value = null;
}
Variable.title = "Variable";
Variable.desc = "store/read variable value";
Variable.LITEGRAPH = 0; //between all graphs
Variable.GRAPH = 1; //only inside this graph
Variable.GLOBALSCOPE = 2; //attached to Window
Variable["@container"] = { type: "enum", values: {"litegraph":Variable.LITEGRAPH, "graph":Variable.GRAPH,"global": Variable.GLOBALSCOPE} };
Variable.prototype.onExecute = function() {
var container = this.getContainer();
if(this.isInputConnected(0))
{
this.value = this.getInputData(0);
if(this.graph)
this.graph.vars[ this.properties.varname ] = this.value;
if(this.properties.global)
global[this.properties.varname] = this.value;
container[ this.properties.varname ] = this.value;
this.setOutputData(0, this.value );
return;
}
this.setOutputData( 0, container[ this.properties.varname ] );
};
Variable.prototype.getContainer = function()
{
switch(this.properties.container)
{
case Variable.GRAPH:
if(this.graph)
return this.graph.vars;
return {};
break;
case Variable.GLOBALSCOPE:
return global;
break;
case Variable.LITEGRAPH:
default:
return LiteGraph.Globals;
break;
}
}
Variable.prototype.getTitle = function() {
return this.properties.varname;
};
@@ -17525,14 +17691,16 @@ if (typeof exports != "undefined") {
LGraphTexture.image_preview_size = 256;
//flags to choose output texture type
LGraphTexture.UNDEFINED = 0; //not specified
LGraphTexture.PASS_THROUGH = 1; //do not apply FX
LGraphTexture.COPY = 2; //create new texture with the same properties as the origin texture
LGraphTexture.LOW = 3; //create new texture with low precision (byte)
LGraphTexture.HIGH = 4; //create new texture with high precision (half-float)
LGraphTexture.REUSE = 5; //reuse input texture
LGraphTexture.DEFAULT = 2;
LGraphTexture.DEFAULT = 2; //use the default
LGraphTexture.MODE_VALUES = {
"undefined": LGraphTexture.UNDEFINED,
"pass through": LGraphTexture.PASS_THROUGH,
copy: LGraphTexture.COPY,
low: LGraphTexture.LOW,
@@ -23104,6 +23272,32 @@ void main(void){\n\
return "";
}
//used to plug incompatible stuff
var convertVarToGLSLType = LiteGraph.convertVarToGLSLType = function convertVarToGLSLType( varname, type, target_type )
{
if(type == target_type)
return varname;
if(type == "float")
return target_type + "(" + varname + ")";
if(target_type == "vec2") //works for vec2,vec3 and vec4
return "vec2(" + varname + ".xy)";
if(target_type == "vec3") //works for vec2,vec3 and vec4
{
if(type == "vec2")
return "vec3(" + varname + ",0.0)";
if(type == "vec4")
return "vec4(" + varname + ".xyz)";
}
if(target_type == "vec4")
{
if(type == "vec2")
return "vec4(" + varname + ",0.0,0.0)";
if(target_type == "vec3")
return "vec4(" + varname + ",1.0)";
}
return null;
}
//used to host a shader body **************************************
function LGShaderContext()
{
@@ -23223,17 +23417,30 @@ void main(void){\n\
// applies a shader graph to texture, it can be uses as an example
function LGraphShaderGraph() {
this.addOutput("out", "texture");
this.properties = { width: 0, height: 0, alpha: false, precision: 0 };
//before inputs
this.subgraph = new LiteGraph.LGraph();
this.subgraph._subgraph_node = this;
this.subgraph._is_subgraph = true;
this.subgraph.filter = "shader";
var subnode = LiteGraph.createNode("output/fragcolor");
subnode.pos = [300,100];
this.subgraph.add( subnode );
this.addInput("in", "texture");
this.addOutput("out", "texture");
this.properties = { width: 0, height: 0, alpha: false, precision: typeof(LGraphTexture) != "undefined" ? LGraphTexture.DEFAULT : 2 };
var inputNode = this.subgraph.findNodesByType("input/uniform")[0];
inputNode.pos = [200,300];
var sampler = LiteGraph.createNode("texture/sampler2D");
sampler.pos = [400,300];
this.subgraph.add( sampler );
var outnode = LiteGraph.createNode("output/fragcolor");
outnode.pos = [600,300];
this.subgraph.add( outnode );
inputNode.connect( 0, sampler );
sampler.connect( 0, outnode );
this.size = [180,60];
this.redraw_on_mouse = true; //force redraw
@@ -23266,6 +23473,7 @@ gl_FragColor = color;\n\
LGraphShaderGraph.title = "ShaderGraph";
LGraphShaderGraph.desc = "Builds a shader using a graph";
LGraphShaderGraph.input_node_type = "input/uniform";
LGraphShaderGraph.output_node_type = "output/fragcolor";
LGraphShaderGraph.title_color = SHADERNODES_COLOR;
LGraphShaderGraph.prototype.onSerialize = function(o)
@@ -23282,15 +23490,21 @@ gl_FragColor = color;\n\
if (!this.isOutputConnected(0))
return;
//read input texture
var intex = this.getInputData(0);
if(intex && intex.constructor != GL.Texture)
intex = null;
var w = this.properties.width | 0;
var h = this.properties.height | 0;
if (w == 0) {
w = gl.viewport_data[2];
w = intex ? intex.width : gl.viewport_data[2];
} //0 means default
if (h == 0) {
h = gl.viewport_data[3];
h = intex ? intex.height : gl.viewport_data[3];
} //0 means default
var type = LGraphTexture.getTextureType(this.properties.precision);
var type = LGraphTexture.getTextureType( this.properties.precision, intex );
var texture = this._texture;
if ( !texture || texture.width != w || texture.height != h || texture.type != type ) {
@@ -23956,8 +24170,16 @@ gl_FragColor = color;\n\
for(var i = 0; i < func_desc.params.length; ++i)
{
var p = func_desc.params[i];
//if( p.type == "T" && inlinks[i].type != base_type )
params.push( inlinks[i].name );
var param_code = inlinks[i].name;
if(param_code == null) //not plugged
{
param_code = "(1.0)";
inlinks[i].type = "float";
}
if( (p.type == "T" && inlinks[i].type != base_type) ||
(p.type != "T" && inlinks[i].type != base_type) )
param_code = convertVarToGLSLType( inlinks[i].name, inlinks[i].type, base_type );
params.push( param_code );
}
context.addCode("code", return_type + " " + outlink + " = "+func_desc.func+"("+params.join(",")+");", this.shader_destination );

View File

@@ -53,7 +53,6 @@
CIRCLE_SHAPE: 3,
CARD_SHAPE: 4,
ARROW_SHAPE: 5,
SQUARE_SHAPE: 6,
//enums
INPUT: 1,
@@ -92,19 +91,10 @@
registered_node_types: {}, //nodetypes by string
node_types_by_file_extension: {}, //used for dropping files in the canvas
Nodes: {}, //node types by classname
Globals: {}, //used to store vars between graphs
searchbox_extras: {}, //used to add extra features to the search box
/**
* Removes all previously registered node's types
*/
clearRegisteredTypes: function() {
this.registered_node_types = {};
this.node_types_by_file_extension = {};
this.Nodes = {};
this.searchbox_extras = {};
},
/**
* Register a node class so it can be listed when the user wants to create a new one
* @method registerNodeType
@@ -1589,8 +1579,10 @@
return;
}
node.graph.beforeChange();
this.inputs[name] = { name: name, type: type, value: value };
this._version++;
node.graph.afterChange();
if (this.onInputAdded) {
this.onInputAdded(name, type);
@@ -1851,6 +1843,22 @@
}
};
//used for undo, called before any change is made to the graph
LGraph.prototype.beforeChange = function(info) {
if (this.onBeforeChange) {
this.onBeforeChange(this,info);
}
this.sendActionToCanvas("onBeforeChange", this);
};
//used to resend actions, called after any change is made to the graph
LGraph.prototype.afterChange = function(info) {
if (this.onAfterChange) {
this.onAfterChange(this,info);
}
this.sendActionToCanvas("onAfterChange", this);
};
LGraph.prototype.connectionChange = function(node, link_info) {
this.updateExecutionOrder();
if (this.onConnectionChange) {
@@ -3134,6 +3142,7 @@
if (!this.inputs) {
this.inputs = [];
}
this.inputs.push(o);
this.setSize( this.computeSize() );
@@ -3221,10 +3230,10 @@
/**
* computes the minimum size of a node according to its inputs and output slots
* @method computeSize
* @param {number} the optional target width
* @param {number} minHeight
* @return {number} the total size
*/
LGraphNode.prototype.computeSize = function(width, out) {
LGraphNode.prototype.computeSize = function(out) {
if (this.constructor.size) {
return this.constructor.size.concat();
}
@@ -3276,7 +3285,7 @@
if (this.widgets && this.widgets.length) {
for (var i = 0, l = this.widgets.length; i < l; ++i) {
if (this.widgets[i].computeSize)
widgets_height += this.widgets[i].computeSize(Math.max(size[0], width || 0))[1] + 4;
widgets_height += this.widgets[i].computeSize(size[0])[1] + 4;
else
widgets_height += LiteGraph.NODE_WIDGET_HEIGHT + 4;
}
@@ -3335,8 +3344,11 @@
if(this.constructor["@" + property])
info = this.constructor["@" + property];
if(this.constructor.widgets_info && this.constructor.widgets_info[property])
info = this.constructor.widgets_info[property];
//litescene mode using the constructor
if (this.onGetPropertyInfo) {
if (!info && this.onGetPropertyInfo) {
info = this.onGetPropertyInfo(property);
}
@@ -3344,6 +3356,8 @@
info = {};
if(!info.type)
info.type = typeof this.properties[property];
if(info.widget == "combo")
info.type = "enum";
return info;
}
@@ -3642,25 +3656,21 @@
return null;
}
var output = this.outputs[slot];
var input = target_node.inputs[target_slot];
if (LiteGraph.isValidConnection(output.type, input.type)) {
if (target_node.onBeforeConnectInput) {
// This way node can choose another slot (if selected is occupied)
target_slot = target_node.onBeforeConnectInput(target_slot);
input = target_node.inputs[target_slot];
}
var changed = false;
//if there is something already plugged there, disconnect
if (target_node.inputs[target_slot].link != null) {
this.graph.beforeChange();
target_node.disconnectInput(target_slot);
changed = true;
}
//why here??
//this.setDirtyCanvas(false,true);
//this.graph.connectionChange( this );
var output = this.outputs[slot];
//allows nodes to block connection
if (target_node.onConnectInput) {
if ( target_node.onConnectInput(target_slot, output.type, output, this, slot) === false ) {
@@ -3668,8 +3678,22 @@
}
}
var input = target_node.inputs[target_slot];
var link_info = null;
//this slots cannot be connected (different types)
if (!LiteGraph.isValidConnection(output.type, input.type))
{
this.setDirtyCanvas(false, true);
if(changed)
this.graph.connectionChange(this, link_info);
return null;
}
if(!changed)
this.graph.beforeChange();
//create link class
link_info = new LLink(
++this.graph.last_link_id,
input.type,
@@ -3726,9 +3750,9 @@
target_slot
);
}
}
this.setDirtyCanvas(false, true);
this.graph.afterChange();
this.graph.connectionChange(this, link_info);
return link_info;
@@ -4564,8 +4588,7 @@ LGraphNode.prototype.executeAction = function(action)
//if(graph === undefined)
// throw ("No graph assigned");
this.background_image =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII=";
this.background_image = LGraphCanvas.DEFAULT_BACKGROUND_IMAGE;
if (canvas && canvas.constructor === String) {
canvas = document.querySelector(canvas);
@@ -4638,6 +4661,9 @@ LGraphNode.prototype.executeAction = function(action)
this.onDrawLinkTooltip = null; //called when rendering a tooltip
this.onNodeMoved = null; //called after moving a node
this.onSelectionChange = null; //called if the selection changes
this.onConnectingChange = null; //called before any link changes
this.onBeforeChange = null; //called before modifying the graph
this.onAfterChange = null; //called after modifying the graph
this.connections_width = 3;
this.round_radius = 8;
@@ -4666,6 +4692,8 @@ LGraphNode.prototype.executeAction = function(action)
global.LGraphCanvas = LiteGraph.LGraphCanvas = LGraphCanvas;
LGraphCanvas.DEFAULT_BACKGROUND_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII=";
LGraphCanvas.link_type_colors = {
"-1": LiteGraph.EVENT_LINK_COLOR,
number: "#AAA",
@@ -5169,15 +5197,17 @@ LGraphNode.prototype.executeAction = function(action)
LiteGraph.closeAllContextMenus(ref_window);
if (this.onMouse) {
if (this.onMouse(e) == true) {
if (this.onMouse)
{
if (this.onMouse(e) == true)
return;
}
}
if (e.which == 1) {
//left button mouse
if (e.ctrlKey) {
if (e.which == 1)
{
if (e.ctrlKey)
{
this.dragging_rectangle = new Float32Array(4);
this.dragging_rectangle[0] = e.canvasX;
this.dragging_rectangle[1] = e.canvasY;
@@ -5214,6 +5244,7 @@ LGraphNode.prototype.executeAction = function(action)
10
)
) {
this.graph.beforeChange();
this.resizing_node = node;
this.canvas.style.cursor = "se-resize";
skip_action = true;
@@ -5321,15 +5352,6 @@ LGraphNode.prototype.executeAction = function(action)
} //not resizing
}
//Search for corner for collapsing
/*
if( !skip_action && isInsideRectangle( e.canvasX, e.canvasY, node.pos[0], node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT ))
{
node.collapse();
skip_action = true;
}
*/
//it wasn't clicked on the links boxes
if (!skip_action) {
var block_drag_node = false;
@@ -5375,6 +5397,7 @@ LGraphNode.prototype.executeAction = function(action)
if (!block_drag_node) {
if (this.allow_dragnodes) {
this.graph.beforeChange();
this.node_dragged = node;
}
if (!this.selected_nodes[node.id]) {
@@ -5682,7 +5705,7 @@ LGraphNode.prototype.executeAction = function(action)
if (this.resizing_node && !this.live_mode) {
//convert mouse to node space
var desired_size = [ e.canvasX - this.resizing_node.pos[0], e.canvasY - this.resizing_node.pos[1] ];
var min_size = this.resizing_node.computeSize(desired_size[0]);
var min_size = this.resizing_node.computeSize();
desired_size[0] = Math.max( min_size[0], desired_size[0] );
desired_size[1] = Math.max( min_size[1], desired_size[1] );
this.resizing_node.setSize( desired_size );
@@ -5874,6 +5897,7 @@ LGraphNode.prototype.executeAction = function(action)
else if (this.resizing_node) {
this.dirty_canvas = true;
this.dirty_bgcanvas = true;
this.graph.afterChange(this.resizing_node);
this.resizing_node = null;
} else if (this.node_dragged) {
//node being dragged?
@@ -5895,6 +5919,7 @@ LGraphNode.prototype.executeAction = function(action)
}
if( this.onNodeMoved )
this.onNodeMoved( this.node_dragged );
this.graph.afterChange(this.node_dragged);
this.node_dragged = null;
} //no node being dragged
else {
@@ -6194,6 +6219,8 @@ LGraphNode.prototype.executeAction = function(action)
return;
}
this.graph.beforeChange();
//create nodes
var clipboard_info = JSON.parse(data);
var nodes = [];
@@ -6221,6 +6248,8 @@ LGraphNode.prototype.executeAction = function(action)
}
this.selectNodes(nodes);
this.graph.afterChange();
};
/**
@@ -6301,12 +6330,14 @@ LGraphNode.prototype.executeAction = function(action)
var ext = LGraphCanvas.getFileExtension(file.name).toLowerCase();
var nodetype = LiteGraph.node_types_by_file_extension[ext];
if (nodetype) {
this.graph.beforeChange();
var node = LiteGraph.createNode(nodetype.type);
node.pos = [e.canvasX, e.canvasY];
this.graph.add(node);
if (node.onDropFile) {
node.onDropFile(file);
}
this.graph.afterChange();
}
}
};
@@ -6465,6 +6496,9 @@ LGraphNode.prototype.executeAction = function(action)
* @method deleteSelectedNodes
**/
LGraphCanvas.prototype.deleteSelectedNodes = function() {
this.graph.beforeChange();
for (var i in this.selected_nodes) {
var node = this.selected_nodes[i];
@@ -6490,6 +6524,7 @@ LGraphNode.prototype.executeAction = function(action)
this.current_node = null;
this.highlighted_links = {};
this.setDirty(true);
this.graph.afterChange();
};
/**
@@ -6944,6 +6979,7 @@ LGraphNode.prototype.executeAction = function(action)
if( this.drawButton( 20,y+2,w - 20, h - 2 ) )
{
var type = subnode.constructor.input_node_type || "graph/input";
this.graph.beforeChange();
var newnode = LiteGraph.createNode( type );
if(newnode)
{
@@ -6957,6 +6993,7 @@ LGraphNode.prototype.executeAction = function(action)
newnode.setProperty("type",input.type);
this.node_dragged.pos[0] = this.graph_mouse[0] - 5;
this.node_dragged.pos[1] = this.graph_mouse[1] - 5;
this.graph.afterChange();
}
else
console.error("graph input node not found:",type);
@@ -7229,44 +7266,6 @@ LGraphNode.prototype.executeAction = function(action)
var temp_vec2 = new Float32Array(2);
LGraphCanvas.prototype.drawSlotGraphic = function(ctx, pos, shape, horizontal) {
ctx.beginPath();
switch (shape) {
case (LiteGraph.BOX_SHAPE):
if (horizontal) {
ctx.rect(
pos[0] - 5 + 0.5,
pos[1] - 8 + 0.5,
10,
14
);
} else {
ctx.rect(
pos[0] - 6 + 0.5,
pos[1] - 5 + 0.5,
14,
10
);
}
break;
case (LiteGraph.ARROW_SHAPE):
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
ctx.closePath();
break;
case (LiteGraph.SQUARE_SHAPE):
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8); //faster
break;
case (LiteGraph.CIRCLE_SHAPE):
default:
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
break;
}
ctx.fill();
}
/**
* draws the given node inside the canvas
* @method drawNode
@@ -7416,9 +7415,39 @@ LGraphNode.prototype.executeAction = function(action)
max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5;
}
var shape = slot.shape || (slot.type === LiteGraph.EVENT && LiteGraph.BOX_SHAPE)
|| (low_quality && LiteGraph.SQUARE_SHAPE) || LiteGraph.CIRCLE_SHAPE;
this.drawSlotGraphic(ctx, pos, shape, horizontal);
ctx.beginPath();
if (
slot.type === LiteGraph.EVENT ||
slot.shape === LiteGraph.BOX_SHAPE
) {
if (horizontal) {
ctx.rect(
pos[0] - 5 + 0.5,
pos[1] - 8 + 0.5,
10,
14
);
} else {
ctx.rect(
pos[0] - 6 + 0.5,
pos[1] - 5 + 0.5,
14,
10
);
}
} else if (slot.shape === LiteGraph.ARROW_SHAPE) {
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
ctx.closePath();
} else {
if(low_quality)
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 ); //faster
else
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
}
ctx.fill();
//render name
if (render_text) {
@@ -7459,11 +7488,46 @@ LGraphNode.prototype.executeAction = function(action)
this.default_connection_color.output_on
: slot.color_off ||
this.default_connection_color.output_off;
ctx.beginPath();
//ctx.rect( node.size[0] - 14,i*14,10,10);
var shape = slot.shape || (slot.type === LiteGraph.EVENT && LiteGraph.BOX_SHAPE)
|| (low_quality && LiteGraph.SQUARE_SHAPE) || LiteGraph.CIRCLE_SHAPE;
this.drawSlotGraphic(ctx, pos, shape, horizontal);
if (
slot.type === LiteGraph.EVENT ||
slot.shape === LiteGraph.BOX_SHAPE
) {
if (horizontal) {
ctx.rect(
pos[0] - 5 + 0.5,
pos[1] - 8 + 0.5,
10,
14
);
} else {
ctx.rect(
pos[0] - 6 + 0.5,
pos[1] - 5 + 0.5,
14,
10
);
}
} else if (slot.shape === LiteGraph.ARROW_SHAPE) {
ctx.moveTo(pos[0] + 8, pos[1] + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5);
ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5);
ctx.closePath();
} else {
if(low_quality)
ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 );
else
ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2);
}
//trigger
//if(slot.node_id != null && slot.slot == -1)
// ctx.fillStyle = "#F85";
//if(slot.links != null && slot.links.length)
ctx.fill();
if(!low_quality)
ctx.stroke();
@@ -8704,7 +8768,14 @@ LGraphNode.prototype.executeAction = function(action)
if(!w || w.disabled)
continue;
var widget_height = w.computeSize ? w.computeSize(width)[1] : LiteGraph.NODE_WIDGET_HEIGHT;
if ( w == active_widget || (x > 6 && x < width - 12 && y > w.last_y && y < w.last_y + widget_height) ) {
//outside
if ( w != active_widget &&
(x < 6 || x > width - 12 || y < w.last_y || y > w.last_y + widget_height) )
continue;
var old_value = w.value;
//if ( w == active_widget || (x > 6 && x < width - 12 && y > w.last_y && y < w.last_y + widget_height) ) {
//inside widget
switch (w.type) {
case "button":
@@ -8844,9 +8915,14 @@ LGraphNode.prototype.executeAction = function(action)
break;
} //end switch
//value changed
if( old_value != w.value )
{
node.graph._version++;
}
return w;
}
}
}//end for
function inner_value_change(widget, value) {
widget.value = value;
@@ -9077,6 +9153,7 @@ LGraphNode.prototype.executeAction = function(action)
function inner_create(v, e) {
var first_event = prev_menu.getFirstEvent();
canvas.graph.beforeChange();
var node = LiteGraph.createNode(v.value);
if (node) {
node.pos = canvas.convertEventToCanvasOffset(first_event);
@@ -9084,6 +9161,7 @@ LGraphNode.prototype.executeAction = function(action)
}
if(callback)
callback(node);
canvas.graph.afterChange();
}
return false;
@@ -9163,8 +9241,10 @@ LGraphNode.prototype.executeAction = function(action)
}
if (v.value) {
node.graph.beforeChange();
node.addInput(v.value[0], v.value[1], v.value[2]);
node.setDirtyCanvas(true, true);
node.graph.afterChange();
}
}
@@ -9271,8 +9351,10 @@ LGraphNode.prototype.executeAction = function(action)
});
return false;
} else {
node.graph.beforeChange();
node.addOutput(v.value[0], v.value[1], v.value[2]);
node.setDirtyCanvas(true, true);
node.graph.afterChange();
}
}
@@ -9299,6 +9381,10 @@ LGraphNode.prototype.executeAction = function(action)
var value = node.properties[i] !== undefined ? node.properties[i] : " ";
if( typeof value == "object" )
value = JSON.stringify(value);
var info = node.getPropertyInfo(i);
if(info.type == "enum" || info.type == "combo")
value = LGraphCanvas.getPropertyPrintableValue( value, info.values );
//value could contain invalid html characters, clean that
value = LGraphCanvas.decodeHTML(value);
entries.push({
@@ -9701,6 +9787,7 @@ LGraphNode.prototype.executeAction = function(action)
name = extra.type;
}
graphcanvas.graph.beforeChange();
var node = LiteGraph.createNode(name);
if (node) {
node.pos = graphcanvas.convertEventToCanvasOffset(
@@ -9739,6 +9826,8 @@ LGraphNode.prototype.executeAction = function(action)
if (extra.data.json) {
node.configure(extra.data.json);
}
graphcanvas.graph.afterChange();
}
}
}
@@ -9870,10 +9959,13 @@ LGraphNode.prototype.executeAction = function(action)
if (type == "string" || type == "number" || type == "array" || type == "object") {
input_html = "<input autofocus type='text' class='value'/>";
} else if (type == "enum" && info.values) {
} else if ( (type == "enum" || type == "combo") && info.values) {
input_html = "<select autofocus type='text' class='value'>";
for (var i in info.values) {
var v = info.values.constructor === Array ? info.values[i] : i;
var v = i;
if( info.values.constructor === Array )
v = info.values[i];
input_html +=
"<option value='" +
v +
@@ -9903,7 +9995,7 @@ LGraphNode.prototype.executeAction = function(action)
options
);
if (type == "enum" && info.values) {
if ((type == "enum" || type == "combo") && info.values) {
var input = dialog.querySelector("select");
input.addEventListener("change", function(e) {
setValue(e.target.value);
@@ -9945,6 +10037,10 @@ LGraphNode.prototype.executeAction = function(action)
}
function setValue(value) {
if(info && info.values && info.values.constructor === Object && info.values[value] != undefined )
value = info.values[value];
if (typeof node.properties[property] == "number") {
value = Number(value);
}
@@ -9952,8 +10048,8 @@ LGraphNode.prototype.executeAction = function(action)
value = JSON.parse(value);
}
node.properties[property] = value;
if (node._graph) {
node._graph._version++;
if (node.graph) {
node.graph._version++;
}
if (node.onPropertyChanged) {
node.onPropertyChanged(property, value);
@@ -10131,7 +10227,10 @@ LGraphNode.prototype.executeAction = function(action)
innerChange(propname, v);
});
}
else if (type == "enum")
else if (type == "enum" || type == "combo")
var str_value = LGraphCanvas.getPropertyPrintableValue( value, options.values );
value_element.innerText = str_value;
value_element.addEventListener("click", function(event){
var values = options.values || [];
var propname = this.parentNode.dataset["property"];
@@ -10169,6 +10268,30 @@ LGraphNode.prototype.executeAction = function(action)
return root;
};
LGraphCanvas.getPropertyPrintableValue = function(value, values)
{
if(!values)
return String(value);
if(values.constructor === Array)
{
return String(value);
}
if(values.constructor === Object)
{
var desc_value = "";
for(var k in values)
{
if(values[k] != value)
continue;
desc_value = k;
break;
}
return String(value) + " ("+desc_value+")";
}
}
LGraphCanvas.prototype.showShowNodePanel = function( node )
{
window.SELECTED_NODE = node;
@@ -10201,7 +10324,9 @@ LGraphNode.prototype.executeAction = function(action)
continue;
panel.addWidget( info.widget || info.type, i, value, info, function(name,value){
graphcanvas.graph.beforeChange(node);
node.setProperty(name,value);
graphcanvas.graph.afterChange();
graphcanvas.dirty_canvas = true;
});
}
@@ -10346,7 +10471,9 @@ LGraphNode.prototype.executeAction = function(action)
}
LGraphCanvas.onMenuNodeCollapse = function(value, options, e, menu, node) {
node.graph.beforeChange(node);
node.collapse();
node.graph.afterChange(node);
};
LGraphCanvas.onMenuNodePin = function(value, options, e, menu, node) {
@@ -10456,7 +10583,9 @@ LGraphNode.prototype.executeAction = function(action)
if (!node) {
return;
}
node.graph.beforeChange(node);
node.shape = v;
node.graph.afterChange(node);
node.setDirtyCanvas(true);
}
@@ -10472,7 +10601,10 @@ LGraphNode.prototype.executeAction = function(action)
return;
}
node.graph.remove(node);
var graph = node.graph;
graph.beforeChange();
graph.remove(node);
graph.afterChange();
node.setDirtyCanvas(true, true);
};
@@ -10505,7 +10637,11 @@ LGraphNode.prototype.executeAction = function(action)
return;
}
newnode.pos = [node.pos[0] + 5, node.pos[1] + 5];
node.graph.beforeChange();
node.graph.add(newnode);
node.graph.afterChange();
node.setDirtyCanvas(true, true);
};

View File

@@ -1029,22 +1029,52 @@
this.size = [60, 30];
this.addInput("in");
this.addOutput("out");
this.properties = { varname: "myname", global: false };
this.properties = { varname: "myname", container: Variable.LITEGRAPH };
this.value = null;
}
Variable.title = "Variable";
Variable.desc = "store/read variable value";
Variable.LITEGRAPH = 0; //between all graphs
Variable.GRAPH = 1; //only inside this graph
Variable.GLOBALSCOPE = 2; //attached to Window
Variable["@container"] = { type: "enum", values: {"litegraph":Variable.LITEGRAPH, "graph":Variable.GRAPH,"global": Variable.GLOBALSCOPE} };
Variable.prototype.onExecute = function() {
var container = this.getContainer();
if(this.isInputConnected(0))
{
this.value = this.getInputData(0);
if(this.graph)
this.graph.vars[ this.properties.varname ] = this.value;
if(this.properties.global)
global[this.properties.varname] = this.value;
container[ this.properties.varname ] = this.value;
this.setOutputData(0, this.value );
return;
}
this.setOutputData( 0, container[ this.properties.varname ] );
};
Variable.prototype.getContainer = function()
{
switch(this.properties.container)
{
case Variable.GRAPH:
if(this.graph)
return this.graph.vars;
return {};
break;
case Variable.GLOBALSCOPE:
return global;
break;
case Variable.LITEGRAPH:
default:
return LiteGraph.Globals;
break;
}
}
Variable.prototype.getTitle = function() {
return this.properties.varname;
};

View File

@@ -34,14 +34,16 @@
LGraphTexture.image_preview_size = 256;
//flags to choose output texture type
LGraphTexture.UNDEFINED = 0; //not specified
LGraphTexture.PASS_THROUGH = 1; //do not apply FX
LGraphTexture.COPY = 2; //create new texture with the same properties as the origin texture
LGraphTexture.LOW = 3; //create new texture with low precision (byte)
LGraphTexture.HIGH = 4; //create new texture with high precision (half-float)
LGraphTexture.REUSE = 5; //reuse input texture
LGraphTexture.DEFAULT = 2;
LGraphTexture.DEFAULT = 2; //use the default
LGraphTexture.MODE_VALUES = {
"undefined": LGraphTexture.UNDEFINED,
"pass through": LGraphTexture.PASS_THROUGH,
copy: LGraphTexture.COPY,
low: LGraphTexture.LOW,

View File

@@ -175,6 +175,32 @@
return "";
}
//used to plug incompatible stuff
var convertVarToGLSLType = LiteGraph.convertVarToGLSLType = function convertVarToGLSLType( varname, type, target_type )
{
if(type == target_type)
return varname;
if(type == "float")
return target_type + "(" + varname + ")";
if(target_type == "vec2") //works for vec2,vec3 and vec4
return "vec2(" + varname + ".xy)";
if(target_type == "vec3") //works for vec2,vec3 and vec4
{
if(type == "vec2")
return "vec3(" + varname + ",0.0)";
if(type == "vec4")
return "vec4(" + varname + ".xyz)";
}
if(target_type == "vec4")
{
if(type == "vec2")
return "vec4(" + varname + ",0.0,0.0)";
if(target_type == "vec3")
return "vec4(" + varname + ",1.0)";
}
return null;
}
//used to host a shader body **************************************
function LGShaderContext()
{
@@ -294,17 +320,30 @@
// applies a shader graph to texture, it can be uses as an example
function LGraphShaderGraph() {
this.addOutput("out", "texture");
this.properties = { width: 0, height: 0, alpha: false, precision: 0 };
//before inputs
this.subgraph = new LiteGraph.LGraph();
this.subgraph._subgraph_node = this;
this.subgraph._is_subgraph = true;
this.subgraph.filter = "shader";
var subnode = LiteGraph.createNode("output/fragcolor");
subnode.pos = [300,100];
this.subgraph.add( subnode );
this.addInput("in", "texture");
this.addOutput("out", "texture");
this.properties = { width: 0, height: 0, alpha: false, precision: typeof(LGraphTexture) != "undefined" ? LGraphTexture.DEFAULT : 2 };
var inputNode = this.subgraph.findNodesByType("input/uniform")[0];
inputNode.pos = [200,300];
var sampler = LiteGraph.createNode("texture/sampler2D");
sampler.pos = [400,300];
this.subgraph.add( sampler );
var outnode = LiteGraph.createNode("output/fragcolor");
outnode.pos = [600,300];
this.subgraph.add( outnode );
inputNode.connect( 0, sampler );
sampler.connect( 0, outnode );
this.size = [180,60];
this.redraw_on_mouse = true; //force redraw
@@ -337,6 +376,7 @@ gl_FragColor = color;\n\
LGraphShaderGraph.title = "ShaderGraph";
LGraphShaderGraph.desc = "Builds a shader using a graph";
LGraphShaderGraph.input_node_type = "input/uniform";
LGraphShaderGraph.output_node_type = "output/fragcolor";
LGraphShaderGraph.title_color = SHADERNODES_COLOR;
LGraphShaderGraph.prototype.onSerialize = function(o)
@@ -353,15 +393,21 @@ gl_FragColor = color;\n\
if (!this.isOutputConnected(0))
return;
//read input texture
var intex = this.getInputData(0);
if(intex && intex.constructor != GL.Texture)
intex = null;
var w = this.properties.width | 0;
var h = this.properties.height | 0;
if (w == 0) {
w = gl.viewport_data[2];
w = intex ? intex.width : gl.viewport_data[2];
} //0 means default
if (h == 0) {
h = gl.viewport_data[3];
h = intex ? intex.height : gl.viewport_data[3];
} //0 means default
var type = LGraphTexture.getTextureType(this.properties.precision);
var type = LGraphTexture.getTextureType( this.properties.precision, intex );
var texture = this._texture;
if ( !texture || texture.width != w || texture.height != h || texture.type != type ) {
@@ -1027,8 +1073,16 @@ gl_FragColor = color;\n\
for(var i = 0; i < func_desc.params.length; ++i)
{
var p = func_desc.params[i];
//if( p.type == "T" && inlinks[i].type != base_type )
params.push( inlinks[i].name );
var param_code = inlinks[i].name;
if(param_code == null) //not plugged
{
param_code = "(1.0)";
inlinks[i].type = "float";
}
if( (p.type == "T" && inlinks[i].type != base_type) ||
(p.type != "T" && inlinks[i].type != base_type) )
param_code = convertVarToGLSLType( inlinks[i].name, inlinks[i].type, base_type );
params.push( param_code );
}
context.addCode("code", return_type + " " + outlink + " = "+func_desc.func+"("+params.join(",")+");", this.shader_destination );