Okay, we admit it: neighbourConstraint is a terrible name for this node. We're looking at creating a more fully-functioned version in the future and we promise that we'll give it a better name then.
The neighbourConstraint node is similar to Maya's animCurveUU node, but with the following additional features:
The neighbourConstraint node also has certain restrictions:
As an example of the neighbourConstraint's use, suppose that we have a curve representing a river and a set of measurements of the current at different points along the river. For each measurement we have its position, which in this case would be its U parameter along the curve, and its value, which would be the speed of the current at that point:
We then have two boats travelling along the river. The current affecting each boat can be interpolated solely on the basis of the current at the sample immediately ahead of the boat, and the current at the sample immediately behind it. Any other current samples further up or downstream have no effect on that boat.
The diagram below shows the river with the sample points marked. For convenience, the two boats are represented by parameterDimension locators, which are shown in yellow. boat1 has been positioned at U value 0.3 while boat2 is at U value 2.5:
The current affecting each boat can be determined by creating a neighbourConstraint node and feeding the current samples into its input attributes, as follows:
createNode -name "nc" neighbourConstraint; setAttr nc.inputs.inputPosition 0; setAttr nc.inputs.inputValue 5; setAttr nc.inputs.inputPosition 1; setAttr nc.inputs.inputValue 8; setAttr nc.inputs.inputPosition 3; setAttr nc.inputs.inputValue 6; setAttr nc.inputs.inputPosition 4; setAttr nc.inputs.inputValue 4;
In this example, the input positions and values are all constant, but they could also be driven by expressions or connections to other attributes. Furthermore, although we entered the samples into the inputs array in order of ascending position, this is not a requirement: they may be entered in any order and the neighbourConstraint node will sort them out correctly.
Next, we feed the positions of the boats into the neighbourConstraint node's targetPositions array, as follows:
connectAttr boat1.uParamValue nc.targetPositions; connectAttr boat2.uParamValue nc.targetPositions;
Now we can retrieve the current affecting each boat from the corresponding element of the targetValues array:
// Get the speed of the current affecting boat1. getAttr nc.targetValues; // Result: 5.9 // // Get the speed of the current affecting boat2. getAttr nc.targetValues; // Result: 6.5 //
Note that instead of directly setting the positions of the boats in the targetPositions array, we connected their uParamValue attributes to the targetPositions array. The advantage of this is that we can move the boats to new positions along the river and the neighbourConstraint node will automatically calculate the current affecting them at their new positions.
In the diagram above, boat1 has been moved to position 1.1, just past the second current sample, and boat2 has been moved to position 3.5, exactly between the third and fourth current samples. If we once again query the neighbourConstraint node for the current affecting each boat at its new position, we get the expected results of 7.9 knots and 5.0 knots:
getAttr nc.targetValues; // Result: 7.9 // getAttr nc.targetValues; // Result: 5.0 //
At this point, you might be wondering why we wouldn't just use an animCurveUU node instead, hooking the boat's U position to the node's input attribute and taking the current affecting it off of the node's.
One reason can be seen by noting that an animCurveUU node only has a single input and a single output attribute. So even though both boats are travelling the same river, with the same currents, you would need a separate animCurveUU for each one. The neighbourConstraint node, however, allows multiple inputs and outputs, so both boats can be handled by a single node.
For an even bigger advantage of the neighbourConstraint node, consider that at any given point along our river, the current remains constant. In the real world, however, currents vary depending upon a number of factors, such as recent rainfall, snowmelt and tides. So let's say that our animation includes a period of rainfall. Shortly after it starts raining, the current should begin to increase, eventually levelling off at some higher rate. Then, sometime after the rain ends, the current should slowly drop back to its original values.
Doing this with the neighbourConstraint node is a snap. Instead of specifying all of the node's inputValues as constants, we can create an expression node for each sample point along the river, and have those expressions calculate the resulting currents after taking rainfall into account. The outputs of the expression nodes can then be connected to the inputValue plugs for each sample point.
This is something that cannot be done with an animCurveUU node because you cannot connect other nodes to its keyTime or keyValue inputs. You have to use the setKeyframe command to change the sample values, which is not a workable solution when an animation is running.
One final note. Although we talk in terms of the positions of the sample points and targets, these need not be physical distances, or even parameter values, but can be any kind of numerical value, such as rotation, light intensity, etc. For example, you might use a neighbourConstraint node to model the glow given off by an electric stove element as it heats up. In such a case, the inputPositions would be various sample temperatures and the inputValues would be the intensity of the element's glow at those temperatures. The targetPositions might then be the current temperatures of several different elements on the stove and targetValues would contain the intensities of their respective glows, as calculated by the neighbourConstraint node.
A neighbourConstraint node's special attributes are found in the Attribute Editor under the Neighbour Constraint heading.
The neighbourConstraint node and its associated materials, which are collectively referred to as "this product", are copyright Gooroos Software, 1999-2004.
Gooroos Software provides this product as-is and assumes no liability for its use. You may freely redistribute it, but only in complete and unmodified form.
If you have any questions or problems with this product, please send email to email@example.com. Because this product is made freely available, we cannot guarantee you a response, but we will try to get back to you as time permits.
For more information on Gooroos Software and our other products, please visit our web-site at www.gooroos.com.