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.
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
tab
on your keyboard and start typingplusMinusAverage
; select the node from the drop-down to create it. - Select the two locator shape nodes and the
plusMinusAverage
and tap3
on the keyboard to reveal the long attribute lists. - Click on the [+] button next to
input3D
on theplusMinusAverage
to expand the ‘multi’ listing. - Connect the
.worldPosition
output ofend_LOCShape
intoinput3D[0]
on theplusMinusAverage
node. - Connect the
.worldPosition
output ofstart_LOCShape
intoinput3D[1]
on theplusMinusAverage
node. - Bring up the Attribute Editor for the
plusMinusAverage
node, and set itsoperation
toSubtract
. - Your Node Editor should now look something like Figure 2. You can pull the vector output from
output3D
on theplusMinusAverage
. To visualise it, try connecting it to thetranslate
input of a new, third locator.
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
persp
to it. - Tap
tab
on the keyboard, start typingvectorProduct
and select from the drop-down list to create it. - With the
vectorProduct1
node selected, bring up the Attribute Editor. Change the node’sOperation
toVector Matrix Product
, and edit the value fields next toinput1
so that they read 0.0, 0.0 and 1.0 respectively. You can ignoreinput2
. - Back in the Node Editor, select both
persp
andvectorProduct1
and bring up the Connection Editor. - Connect
worldMatrix
on the left intomatrix
on the right. - Your Node Editor should now look something like Figure 4. You can read or connect the vector from the
vectorProduct
node’soutput
attribute.
pointMatrixMult
node instead of a vectorProduct
, but make sure the pointMatrixMult
’s .vectorMultiply
attribute is on.