Get Vectors Using Scripts or Nodes
Like point coordinates, vectors have three components. However, they don't describe a position; rather, they describe a direction and a magnitude. These are key to defining an object’s orientation and scaling, respectively.
Vectors are the constituent parts of matrices. Understanding how to construct and manipulate them throws up many possibilities for creative rigging in Maya.
This article will explore two ways of reading vectors in Maya, start / end subtraction and axis extraction. You can think of these as analogues for the Object Up and Object Rotation Up up-vector settings on, say, aimConstraint nodes.
Both script- and node-based methods will be discussed.
Getting Vectors via Start / End Subtraction
Subtracting each coordinate of a start point from each coordinate of an end point yields three values that make up a vector.
This vector tells you how far you need to travel from the start point, and in what direction, to reach the end point.
Script Method
Probably the easiest way to work with vectors in scripts is using PyMEL’s data types. This is because:
- They are far more concise than the Maya API, and implement many of its functions as direct methods.
- They work with simple operators like + and -, without the need to wrangle separate vector components.
Figure 1.
In the following example I am getting the world-space positions of two locators, start_LOC and end_LOC, and subtracting them to yield a vector.
startPosition = p.xform("start_LOC",q=True,ws=True,t=True)
startPosition = p.datatypes.Point(startPosition)
endPosition = p.xform("end_LOC",q=True,ws=True,t=True)
endPosition = p.datatypes.Point(endPosition)
startEndVector = p.datatypes.Vector(endPosition-startPosition)
Node Method
To calculate the vector between two points in a dynamic node network instead of a script, use a plusMinusAverage node.
To try it:
- Create two locators, start_LOC and end_LOC, as per the earlier example and move them apart in the viewport.
- Pull up the Node Editor and add the locators’ shape nodes (not transforms) to it.
- Tap
tabon your keyboard and start typingplusMinusAverage; select the node from the drop-down to create it. - Select the two locator shape nodes and the
plusMinusAverageand tap3on the keyboard to reveal the long attribute lists. - Click on the [+] button next to
input3Don theplusMinusAverageto expand the ‘multi’ listing. - Connect the
.worldPositionoutput ofend_LOCShapeintoinput3D[0]on theplusMinusAveragenode. - Connect the
.worldPositionoutput ofstart_LOCShapeintoinput3D[1]on theplusMinusAveragenode. - Bring up the Attribute Editor for the
plusMinusAveragenode, and set itsoperationtoSubtract. - Your Node Editor should now look something like Figure 2. You can pull the vector output from
output3Don theplusMinusAverage. To visualise it, try connecting it to thetranslateinput of a new, third locator.
Figure 2.
xform or the worldPosition attribute on locator shapes).
If you know that the objects will remain at the scene root level, you can read or connect their translate channels instead for a simpler setup.
Check out Get World Positions Using Scripts or Nodes for more information on reading the world position of Maya transforms.
Getting Vectors via Axis Extraction
Sometimes it’s useful to extract one or more of an object’s orientation axes as a vector.
You can do this by multiplying the ‘base’ vector that corresponds to the axis letter (for example [1,0,0] for the x-axis) with the object’s world-space matrix.
Script Method
Here’s how to extract the persp camera’s Z-axis as a vector:
camera = p.PyNode('persp')
cameraWorldMatrix = camera.getMatrix(worldSpace=True)
zAxisBaseVec = p.datatypes.Vector([0,0,1])
cameraWorldZAxisAsVec = zAxisBaseVec * cameraWorldMatrix
Node Method
Here’s how to achieve the same thing using a dynamic node network in Maya:
- Pull up the Maya Node Editor and add
perspto it. - Tap
tabon the keyboard, start typingvectorProductand select from the drop-down list to create it. - With the
vectorProduct1node selected, bring up the Attribute Editor. Change the node’sOperationtoVector Matrix Product, and edit the value fields next toinput1so that they read 0.0, 0.0 and 1.0 respectively. You can ignoreinput2. - Back in the Node Editor, select both
perspandvectorProduct1and bring up the Connection Editor. - Connect
worldMatrixon the left intomatrixon the right. - Your Node Editor should now look something like Figure 4. You can read or connect the vector from the
vectorProductnode’soutputattribute.
pointMatrixMult node instead of a vectorProduct, but make sure the pointMatrixMult’s .vectorMultiply attribute is on.
Figure 3.
Figure 4.