This project stands or falls on your contribution.
Besides lots of todos regarding the core system, hundreds of nodes want to be ported. Some of them being complex, but also many simple ones, which can be implemented quicker than you can say some phrase of medium length.
It's very easy to write your own nodes. Basically the only thing you need is a text editor. However, the best way to get your nodes into the VVVV.js repository on GitHub is to follow these steps:
VVVV.Nodes.AddValue = function(id, graph) {
this.constructor(id, "Add (Value)", graph);
this.meta = {
authors: ['Matthias Zauner'],
original_authors: ['VVVV Group'],
credits: [],
compatibility_issues: []
};
var input1In = this.addInputPin("Input 1", [0.0], this);
var input2In = this.addInputPin("Input 2", [0.0], this);
var outputOut = this.addOutputPin("Output", [0.0], this);
this.evaluate = function() {
if (input1In.pinIsChanged() || input2In.pinIsChanged()) {
var maxSpreadSize = this.getMaxInputSliceCount();
for (var i=0; i<maxSpreadSize; i++) {
outputOut.setValue(i, parseFloat(input1In.getValue(i)) + parseFloat(input2In.getValue(i)));
}
}
}
}
VVVV.Nodes.AddValue.prototype = new VVVV.Core.Node(); // quasi inheritance
The first few lines are pretty obvious: choose an object name prefixed by the VVVV.Nodes namespace. Call the "base class" constructor by supplying the nodename ("Add (Value)" in this example), and adjust the this.meta object.
The lines
var input1In = this.addInputPin("Input 1", [0.0], this);
var input2In this.addInputPin("Input 2", [0.0], this);
var outputOut = this.addOutputPin("Output", [0.0], this);
create in- and output pins. The first argument refers to the pin name, the second one is the default value. In VVVV.js, spreads are simply arrays, there's no explicit spread data structure.
Note in the example above, that [0.0] means a default value of a one-sliced spread. You'll always have to supply an array here, even if the default value is just one slice.
Let's have a look at the evaluate function, which is called every frame.. There are three methods you'll need:
if (input1In.pinIsChanged() ...) ...Using the pinIsChanged() method, you can find out, if an input pin has changed during the last frame, and therefore the node has to be evaluated. This helps you creating a clever path through your node, which saves ressources by only calculating, if really needed.
var maxSpreadSize = this.getMaxInputSliceCount();gives you the maximum slice count of all input pins.
input1In.getValue(i);returns the i-th slice of the input1In input pin. This method does an automatic modulo operation on the index, meaning that, if you call inputpin.getValue(10) on a pin with a spread of 8 slices, the 2nd slice will be returned.
outputOut.setValue(i, ...)sets the i-th slice of an output pin. This will cause the pinIsChanged() method in other nodes, which are connected to this pin, to return true. There's no explicit setPinIsChanged() method as in pure VVVV. Also note, that here the index is not auto-moduloed.
inputPin.values.lengthAs you can see, you can access the values property of a pin directly. However, writing directly into the values array will not set the changed flag for the pin.
this.meta = {
authors: ['Your name', 'this other guy\'s name'],
original_authors: ['The author of the original VVVV node, if any exists'],
credits: ['papers', 'websites', 'books', 'libraries', 'and other sources used do develope the node'],
compatibility_issues: ['issue1', 'issue2']
};
Note that the object properties are all arrays. Authors, original authors and credits should be pretty clear. The compatibility_issues property should contain issues, which describe the progress
of node development, regarding the range of functionality of the original VVVV node. Use the following checklist, to find out what to put in here:
There might be some VVVV.js nodes, that don't exist in pure VVVV (for example the whole Canvas category). To be able to create those nodes in VVVV, we use (dummy) modules.
If you write a node which doesn't have an original VVVV counterpart, create a module with the full nodename as filename (e.g. "BezierCurve (Canvas VVVVjs).v4p"), and place it into the vvvv_js_modules directory. Add the input and output pins, named just like in the javascript code. You can leave the module empty, or add some dummy behaviour. For example, the BezierCurve (Canvas VVVVjs) node, uses the original VVVV's BezierLine (GDI) node, to get at least some output for developing purposes.