Articles

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.

import pymel.core as p

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:

  1. Create two locators, start_LOC and end_LOC, as per the earlier example and move them apart in the viewport.
  2. Pull up the Node Editor and add the locators’ shape nodes (not transforms) to it.
  3. Tap tab on your keyboard and start typing plusMinusAverage; select the node from the drop-down to create it.
  4. Select the two locator shape nodes and the plusMinusAverage and tap 3 on the keyboard to reveal the long attribute lists.
  5. Click on the [+] button next to input3D on the plusMinusAverage to expand the ‘multi’ listing.
  6. Connect the .worldPosition output of end_LOCShape into input3D[0] on the plusMinusAverage node.
  7. Connect the .worldPosition output of start_LOCShape into input3D[1] on the plusMinusAverage node.
  8. Bring up the Attribute Editor for the plusMinusAverage node, and set its operation to Subtract.
  9. Your Node Editor should now look something like Figure 2. You can pull the vector output from output3D on the plusMinusAverage. To visualise it, try connecting it to the translate input of a new, third locator.

Figure 2.

This tutorial so far has used explicitly world-space coordinates (i.e. via 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:

import pymel.core as p

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:

  1. Pull up the Maya Node Editor and add persp to it.
  2. Tap tab on the keyboard, start typing vectorProduct and select from the drop-down list to create it.
  3. With the vectorProduct1 node selected, bring up the Attribute Editor. Change the node’s Operation to Vector Matrix Product, and edit the value fields next to input1 so that they read 0.0, 0.0 and 1.0 respectively. You can ignore input2.
  4. Back in the Node Editor, select both persp and vectorProduct1 and bring up the Connection Editor.
  5. Connect worldMatrix on the left into matrix on the right.
  6. Your Node Editor should now look something like Figure 4. You can read or connect the vector from the vectorProduct node’s output attribute.
You can use a pointMatrixMult node instead of a vectorProduct, but make sure the pointMatrixMult’s .vectorMultiply attribute is on.

Figure 3.

Figure 4.

TutorialsKimon Matara