Maya Tutorial - Expressions
Maya Tutorial - Expressions
Maya Tutorial - Expressions
Expressions
3 Introducing Expressions 11
About expressions 12
Where you create expressions 13
4 Quick Start 15
Preparing for the examples 15
Creating a simple expression 17
Controlling multiple attributes of an object 23
Controlling attributes in two objects 28
Controlling attributes conditionally 32
Notes on the predefined time variable 43
5 Expression Syntax 45
Expressions and MEL 46
Elements of an expression 47
Attributes 49
Static attributes 49
Dynamic attributes 49
Custom attributes 50
Attribute names 51
Data types of attributes 51
Assigning a value to an attribute 55
Variables 56
Data types of variables 57
Predefined variables 57
Custom variables 59
Constants 62
Arithmetic, logic, and relational operators 63
Arithmetic operators 63
Relational operators 65
Logical operators 67
Operator precedence 68
Conditional statements 69
if statements 69
if-else statements 70
else if statements 71
General syntax rules 73
Comments in expressions 75
Programming features 75
Notes for C programmers 75
Expression language keywords 76
Flow control statements 77
Flow control errors 88
String usage 90
Shortcut assignment operators 91
Shortcut increment and decrement operators 92
Arrays 93
Boolean symbolic constants 95
Common expression errors 95
Error message format 95
Common error messages 97
6 Editing Expressions 99
Finding expressions 99
Finding by expression name 100
Finding by selected object 101
9 Functions 203
Understanding functions 205
Function syntax 206
Data types 208
Understanding function examples in this chapter 208
Limit functions 209
abs 209
ceil 210
floor 210
clamp 211
min 212
max 212
sign 212
trunc 213
Exponential functions 214
exp 214
log 214
log10 214
pow 215
sqrt 215
Trigonometric functions 216
cos 216
cosd 218
sin 219
sind 224
tan 224
tand 225
acos 225
acosd 226
asin 226
asind 226
atan 227
atand 227
atan2 227
atan2d 228
hypot 228
Vector functions 229
angle 229
cross 230
dot 231
mag 231
rot 232
unit 233
Conversion functions 234
deg_to_rad 234
rad_to_deg 234
hsv_to_rgb 235
rgb_to_hsv 235
Array functions 236
clear 236
size 237
sort 237
Random number functions 239
gauss 239
noise 241
dnoise 242
rand 243
sphrand 244
seed 246
Curve functions 249
linstep 249
smoothstep 252
hermite 254
General commands 259
eval 259
print 261
system 263
Other functions and commands 264
Expressions are instructions you type to control an object attribute over time.
An attribute is a characteristic of an object, for instance, X scale, Y translate,
visibility, and so on.
Though you can create an expression to animate attributes for any purpose,
they’re ideal for attributes that change incrementally, randomly, or
rhythmically over time.
Expressions
Eric Saindon
Expressions are also useful for linking attributes between different objects—
where a change in one attribute alters the behavior of the other. For instance,
you can make the rotation of a tire dependent on the forward or backward
movement of a car.
This chapter has the following topics:
• “About expressions” on page 12
• “Where you create expressions” on page 13
About expressions
Expressions offer an alternative to difficult keyframing tasks. In keyframing,
you set the values of attributes at selected keyframes in the animation, and
Maya interpolates the action between the keyframes. With expressions, you
write a formula, then Maya performs the action as the animation plays.
Expressions are often as simple as a few words or lines. In the following
example expressions, note the variation in length and detail (rather than
their purpose).
Example
Ball.translateX = Cube.translateX + 4;
Example
if (frame == 1)
Cone.scaleY = 1;
else
{
Cone.scaleY = (0.25 + sin(time)) * 3;
print(Cone.scaleY + "\n");
}
Though many expressions look like math or a programming language, you
don’t need to be a mathematician or programmer to learn how to use them.
If you’re fond of programming, expressions offer unlimited animation
techniques that would challenge the skill of keyframing experts.
You can use an expression to animate any keyable, unlocked object attribute
for any frame range. You can also use an expression to control per particle or
per object attributes. Per particle attributes control each particle of an object
individually. Per object attributes control all particles of an object
collectively.
You cannot apply an expression to an attribute already animated with any of
these techniques:
• keys
• set driven key
• constraint
• motion path
• another expression
• any other direct connection
If you do so, you’ll see an error message in the Script Editor and the
Command Line’s response area.
Though you can’t control a single attribute with two of the preceding
techniques, you can control one attribute with keyframes, another with an
expression, another with a constraint, and so on.
Also, you can use a single expression to assign values to several attributes of
one or more objects.
Expressions
You cannot start the Expression Editor from every attribute text field in the
Channel Box and Attribute Editor. Use Window→Expression Editor if
necessary.
The expression text field expands as you type text, so you can write
expressions of unlimited length. You can also edit expressions with a text
editor such as jot by selecting it from the Editor pull-down menu above the
text field.
The easiest way to learn about expressions is to work through examples. For
this reason, we provide the following introductory lessons. Expressions that
control particle attributes are more complex than for other objects. For
examples, see Chapter 8, “Particle Expressions.”
Expressions
In this chapter, you’ll learn about the following topics:
• “Creating a simple expression” on page 17
• “Controlling multiple attributes of an object” on page 23
• “Controlling attributes in two objects” on page 28
• “Controlling attributes conditionally” on page 32
• “Notes on the predefined time variable” on page 43
5 Enter 0 for the starting frame of the Time Slider and the Range Slider, and
enter 300 for the ending frame of the Time Slider and Range Slider.
Important
For the lessons to work correctly, you must enter 0 for the starting frame of
the Time Slider and Range Slider. Press your keyboard’s Enter key after
each entry. Rewind the animation to frame 0. After doing the lessons, read
“Notes on the predefined time variable” on page 43 for details on why the
lessons require the starting frame to be 0.
Specifying a range of 300 frames gives ample time to see the effects you’ll
create in the examples.
6 In the General Preferences window, click Save and Close.
7 At the top edge of the workspace, select Shading→Smooth Shade All to
display all objects you create in the scene with smooth shading.
This will enhance the look of the objects you create in the examples.
8 From the menu bar, choose Window→Expression Editor to display the
Expression Editor.
9 Make sure these default Expression Editor menu options are selected:
Select Filter→By Object/Attribute Name
Object Filter→Selected Objects
Attribute Filter→All
“Finding expressions” in Chapter 6 gives details on these options.
Expressions
3 Select Display→NURBS Smoothness→Fine to set Ball’s display smoothness
to fine resolution.
Maya displays the object with extra polygons to make it look smoother in
the workspace. This doesn’t affect the underlying model’s geometry. It alters
only its display.
Ball.scaleY = time + 1;
Enter the expression with the same upper and lowercase spelling shown.
Entries in the expression field are type case sensitive.
The semicolon (;) signifies the end of the expression statement. Each
statement in an expression must end with a semicolon. The only exception is
when the expression has a single statement.
An error message appears in the Script Editor and Command Line’s
response area if the expression has incorrect syntax or typing mistakes.
Edit text the same way you edit other text fields in Maya.
0 0
1 0.0417
2 0.0833
Expressions
3 0.125
24 1.0
240 10.0
If you ever need to change the playback rate, you can do so by choosing
Options→General Preferences. Expand the General Preferences window,
display the Units folder, and choose the desired rate from the Time menu.
Regardless of what animation playback rate you choose, you can find the
time elapsed in the animation at any frame with this formula:
frame
time = ---------------
rate
For example, if the frame rate is 24 frames/second and the animation is at
frame 1, the elapsed time is 1 divided by 24, or 0.0417. At frame 6, the
elapsed time is 6 divided by 24, which equals 0.25.
0 0 1
1 0.0417 1.0417
2 0.0833 1.0833
3 0.125 1.125
24 1.0 2.0
Maya executes the expression each frame. This causes the object size to scale
along its Y-axis, stretching its height during playback.
The scaling is smooth because the geometry stretches in synch with the small
time increments of the animation playback.
Expressions
• remembering the name of the expression
• remembering the name of the object and attribute you controlled with the
expression
• examining each expression in the scene that’s controlled by an expression
In this example, you’ll find the expression ScaleBallHeight by its name. See
Chapter 6, “Editing Expressions” for details on the other methods.
2 Choose Select Filter→By Expression Name.
3 Click ScaleBallHeight in the Expressions list.
The expression appears in the expression text field.
Ball.scaleY = time + 1;
Summary
In this lesson, you learned how to:
• name an expression and type it in the expression text field
Expressions
To prepare the scene:
1 From the Modeling menu, choose Primitives→Create NURBS→Sphere.
This creates a NURBS sphere with an X scale, Y scale, and Z scale of 1.
2 In the Channel Box or elsewhere, name the sphere Planet.
3 Select Display→NURBS Smoothness→Fine to set the Planet’s display
smoothness to fine resolution.
4 Display the Expression Editor and select Select Filter→By Object/Attribute
Name.
5 Rewind the animation to frame 0.
This names the expression so you can find it more easily later.
3 Enter these statements in the expression text field:
The expression has three statements. Each statement sets an attribute to the
value of the predefined variable time.
4 Click Create to compile the expression.
An error message appears in the Script Editor and Command Line’s
response area if the expression has incorrect syntax.
Planet disappears because clicking Create also executes the expression at the
current frame after compiling. At frame 0, time is 0, so the value of the
scaleX, scaleY, and scaleZ attributes becomes 0. Planet has no size, so it
disappears.
Expressions
Planet.scaleX = time;
Planet.scaleY = Planet.scaleX;
Planet.scaleZ = Planet.scaleX;
2 Click Edit to compile the expression.
3 Play the animation.
The expression works the same as the previous one. The first statement sets
Planet.scaleX to the value of time.
The second statement sets Planet.scaleY to the value of Planet.scaleX.
Because you’ve set Planet.scaleX to the value of time, Planet.scaleY also has
the value of time. You’re simply transferring one attribute’s value to another.
The third statement also sets Planet.scaleZ to the value of the attribute
Planet.scaleX.
The next three statements assign the contents of $increment to the three scale
attributes of Planet. The scale attributes therefore receive the value of time
divided by 5 each frame. This makes the object increase uniformly in scale
slowly as the animation plays.
2 Click Edit.
3 Play the animation.
The result is the same as with the previous expression
4 Stop and rewind the animation.
You can make a change to the variable assignment in the second statement
without altering the other statements.
Expressions
Because you assigned time * 2 to the variable $increment, the expression sets
all three attributes to the value of time * 2 as the animation plays. This makes
the three scale attributes increase at a rate twice as fast as would occur if you
assigned them the value of time alone.
4 Stop and rewind the animation.
This concludes the example. Before starting the next example, delete the
scene and create a new scene.
Summary
In this lesson, you learned how to:
• link multiple attributes of the same object with a single expression
• use a variable you defined in an expression
• modify a single assignment to an attribute without changing other
statements
To see an object’s local rotation axes, select the object, then choose
Display→Object Components→Local Rotation Axes.
Each object rotates around its local X-axis by the degree value resulting from Expressions
time * 10. After 1 second, for example, the rotateX attribute of each object is
one degree times 10, or 10 degrees. After 2 seconds, it’s 2 degrees times 10,
or 20 degrees.
Maya works in degree angle units, by default. You can change the angular
units to radians by choosing Options→General Preferences and displaying
the Units folder.
With the animation playing at 24 frames per second, each object’s rotateX
attribute has these values:
0 0 0
1 0.0417 0.417
2 0.0833 0.833
3 0.125 1.25
24 1.0 10
The values in this chapter are rounded to four significant digits. The actual
values might have many more digits.
To see the degree value of Can.rotateX at different frames, select Can,
display the Channel Box, and stop the animation at selected frames. The
Channel Box updates its values after you stop the animation.
To see the degree value of Cone.rotateX at different frames, select Cone
instead of Can. The Channel Box displays values for the selected object.
2 Stop and rewind the animation.
You can edit the expression to make Can rotate slower than Cone.
Expressions
statements are in a single expression. You don’t need to edit two
expressions.
Before starting the next example, delete the scene and create a new scene.
Summary
In this lesson, you learned how to:
• control rotateX attributes in two objects using the same expression
• increase the rotation of each object in synch with animation time
• rotate one object at half the speed of the other object
Important
When you compare the value of time to a number in an expression, Maya
interprets time as seconds rather than milliseconds, minutes, or any other
unit of time. In the example, Maya interprets 2 as 2 seconds.
The expression checks whether the value of time is less than two seconds. If
so, it does the assignment Balloon.scaleY = time. If time is not less than two
seconds, the assignment doesn’t occur.
Notice the indentation of Balloon.scaleY = time under if (time < 2). Maya
ignores all indentation, extra spaces, and blank lines between statements. We
used the indentation to make the expression easier to read. You could have
also written the expression as follows:
if (time < 2) Balloon.scaleY = time;
This isn’t as easy to read. Consistent, organized spacing is a good habit to
develop. This book shows examples of good spacing style.
4 Click Create to compile the expression.
Balloon flattens.
Expressions
The expression executes when you click the Create button. Because the
animation is at frame 0, animation time is 0. Because time is less than 2,
Maya sets Balloon.scaleY equal to the value of time, which equals 0.
A scaleY value of 0 flattens the object in the Y dimension.
5 Play the animation.
The flattened Balloon’s scale increases along its Y-axis. It inflates as the
animation plays.
0 0 0
1 0.0417 0.0417
2 0.0833 0.0833
3 0.125 0.125
24 1.0 1.0
47 1.96 1.9583
48 2.0 1.9583
49 2.04 1.9583
The if statement’s condition, (time < 2), is a comparison. The condition must
be surrounded by parentheses to isolate it from assignment that follows it.
Expressions
Balloon inflates for 2 seconds. After 2 seconds, Balloon stops inflating and its
position skips from a Y-axis position of 0 to 2. You’ll eliminate the motion
skip in a later step.
The second if statement increases the translateY position of Balloon after the
animation time rises above two seconds. The >= symbols mean greater than
or equal to. Whenever time is greater than or equal to 2, the expression
assigns Balloon’s translateY the value of time. The translateY value therefore
increases for the rest of your animation’s playback range.
Notice that a semicolon ends each statement. Forgetting a semicolon after
each statement causes a syntax error, and the changes you’ve made to the
expression won’t take effect.
Important
Always examine the Script Editor for error messages after you edit an
expression and click the Create button. If you alter a previously successful
expression and a syntax error occurs, Maya executes the previous
successful expression when you play the animation. This might make you
believe your editing changes took effect.
Balloon doesn’t return to the origin because the expression doesn’t assign
Balloon a starting point for the beginning of the animation.
5 To make Balloon return to the origin, change the expression to this:
if (time == 0)
Balloon.translateY = 0;
if (time < 2)
Balloon.scaleY = time;
if (time >= 2)
Balloon.translateY = time;
The new first statement sets Balloon.translateY to 0 whenever time equals 0.
The == symbols mean is equal to. In conditional statements, be careful to type
== rather than =. The = symbol means assign the value to.
Note that you can put the three statements in any order in this example.
When Maya plays each frame, it executes each statement in the expression in
the order listed. In this example, the statements work independently, so their
order doesn’t matter.
We put the statements in the order of time execution because it’s easier to
see the logic of the expression. If you ever need to change the expression,
you’ll be able to grasp the expression’s actions more quickly.
6 Click Edit.
7 Stop and rewind the animation again.
The flattened Balloon returns to its correct position at the origin.
Expressions
As mentioned before, Balloon skips from Y-axis position 0 to 2 after two
seconds of animation play. You can eliminate the skipping and make
Balloon rise smoothly from the origin.
Balloon inflates for 2 seconds, then rises slowly with time from its position at
the origin.
When time is greater than or equal to 2, the translateY position of Balloon
becomes 2 minus 2, which is 0. As time increases beyond 2 seconds, the
translateY position increases in the same increments that time increases.
if (time < 2)
Balloon.scaleY = time;
else
Balloon.translateY = time - 2;
2 Click Edit.
3 Play the animation.
The else keyword sets Balloon.translateY to time - 2 when (time < 2) is false.
In English terms, the combination of the if and else statements says, “If time
is less than two seconds, set Balloon.scaleY to the value of time. Otherwise
(when time is greater than or equal to two seconds), set Balloon.translateY to
time minus two.”
Expressions
To make the expression easier to read:
1 Change the expression to this:
if (time < 2)
{
Balloon.translateY = 0;
Balloon.scaleY = time;
}
else
Balloon.translateY = time - 2;
We removed this statement from the previous version of the expression:
if (time == 0)
Balloon.translateY = 0;
In its place, we put the statement Balloon.scaleY = time in a segment
enclosed by the braces { and }. Maya evaluates both the statements between
the braces if the condition (time < 2) is true.
2 Click Edit.
Expressions
To further refine Balloon’s appearance:
1 Change the expression to this:
if (time < 2)
{
Balloon.translateY = 0;
Balloon.scaleY = time * 0.6;
Balloon.scaleX = time * 0.5;
Balloon.scaleZ = time * 0.5;
}
else
Balloon.translateY = time - 2;
2 Click Edit.
Balloon disappears from view because its scale attributes are 0.
The scaleX, scaleY, and scaleZ attributes are 0 at frame 0 because time is 0.
Any number multiplied by 0 is 0.
3 Play the animation.
Summary
Using an expression is a combination of logic and experimentation. Problem
solving starts with breaking a task into smaller problems you can solve and
later refine.
In this lesson, you learned how to:
• control an attribute conditionally with an if statement
• use good spacing and indentation for expressions
• use relational operators such as <, <=, and ==
• use multiple if statements to control different conditions
• use an if-else statement in place of multiple if statements to make an
expression easier to read and comprehend
• refine an expression with a combination of analysis and experimentation
Expressions
value of Ball’s scaleY attribute to time + 1, which equals 0.0417 + 1, or 1.0417.
Because Ball’s scaleY attribute was 1 when you created it, rewinding the
animation sets scaleY to a value 0.0417 larger than its initial value.
This discrepancy means the Ball scaleY is larger than its scaleX and scaleZ
attributes in the first frame of the animation. Though the difference is not
substantial in this example, other cases might be more significant.
To start your animation at frame 1 and get the same result as the example,
you can subtract 0.0417 from the attribute:
Ball.scaleY = (time - 0.0417) + 1;
When you rewind the animation, the expression sets Ball’s scaleY value to
(0.0417 - 0.0417) + 1. This equals 1, its original scaleY value.
When you use the predefined time variable, be aware of the starting frame
number and the associated time value.
After doing the lessons in this chapter, remember to change your Time
Slider’s starting frame, ending frame, and frame rate to the desired values
when you start other projects. To do this, select Options→General
Preferences and display the appropriate tabs in the General Preferences
window.
Expressions
rotation.
Tristan Ikuta
This chapter describes the following topics:
• “Expressions and MEL” on page 46
• “Elements of an expression” on page 47
• “Attributes” on page 49
• “Variables” on page 56
• “Constants” on page 62
• “Arithmetic, logic, and relational operators” on page 63
• “Operator precedence” on page 68
• “Conditional statements” on page 69
• “General syntax rules” on page 73
• “Comments in expressions” on page 75
Elements of an expression
An expression is made of one or more statements. Statements follow the
rules of algebra, so they’ll seem familiar if you’ve studied math. Each
statement has several elements as in the following example:
Statement
Variable
Expressions
=. In the example, Ball.rotateZ receives the value of the
statement sin(time) + 6. (Ignore what this assignment does;
it’s for illustration only.) You can also use = to assign a value
to a variable.
Function A special word that you provide with an entry called an
argument. In this example, the argument is time. Based on
the value of the argument, Maya does a calculation for the
function and returns a new value or takes some other action.
In the example, the function sin(time) returns the sine of the
value of time, which evaluates to a number between -1 and
1.
Maya has many convenient built-in functions and
commands that do math calculations, conversions, and so
on. See Chapter 9 for details.
Example
Here’s an expression with the fewest elements possible:
Value assigned
Ball.scaleY = 5;
Attributes
An attribute is a characteristic of an object or other item in a scene. There are
many ways to set attributes in Maya—with the Attribute Editor, Channel
Box, menu selections, and of course, expressions. You can set attributes to
control virtually anything in your animation.
There are three types of attributes you work with in Maya:
• static
• dynamic
• custom
Static and dynamic attributes have a predefined purpose. They are standard
attributes Maya provides for objects and items that make up a scene. Custom
attributes are attributes you define for an object.
Static attributes
Static attributes are attributes an object has by default. They exist the
moment you create the object and throughout its lifetime.
For example, the transform node of a NURBS sphere has static attributes
scaleX, scaleY, scaleZ, rotateX, and so on. You can set the values of these
attributes with the Attribute Editor, Channel Box, expressions, and other
Expressions
techniques after you create the object.
Dynamic attributes
Dynamic attributes have predefined names and purposes, but Maya adds
them to an object in response to your user interface selections.
For example, suppose you create a particle object and display its particle
shape folder in the Attribute Editor. If you click one of the following buttons
in the Add Dynamic Attributes section of the Attribute Editor, Maya adds a
dynamic attribute to the node:
Clicking the General button lets you add a custom attribute (see the next
topic). Clicking any of the other buttons lets you add one or more dynamic
attributes with names that are the same or similar to the button name.
An object has no dynamic attributes unless your actions cause Maya to add
them to the object. By adding only required attributes, Maya runs faster.
When you add a dynamic attribute to an object, the attribute appears in the
Attribute editor for the selected object or node.
Note
Because soft body geometry is a particle shape node coupled with
geometry, a soft body has the same static and dynamic attributes as a
particle object.
Custom attributes
Custom attributes are attributes you optionally add from the New folder of
the Add Attribute window.
Attribute names
Static, dynamic, and custom attributes follow the same naming conventions
and represent the same types of data.
A full attribute name has this format:
object.attribute
where object is the name of the object node, and attribute is the name of the
attribute. A period (.) separates the name of the object and attribute.
You must spell the object and attribute name with uppercase and lowercase
letters as they appear in the Expression Editor’s Objects and Attributes lists.
Expressions
You cannot spell attribute names with the common English spellings shown
in the Attribute Editor or by default in the Channel Box.
See “Using attribute names in expressions” in Chapter 6 for more details.
Example
Ball.scaleY
Note
Scientists often refer to a vector as a quantity that specifies both a
magnitude and direction. In Maya, a vector is simply a related group of
three floating point numbers that set an attribute or variable.
Vector array data types are useful for animating position, velocity,
acceleration, color, and other particle attributes made of three components.
Float array attributes are useful for setting lifespan, opacity, and other
particle attributes that have a single number value.
Attributes having a vector array or float array data type are also called per
particle attributes. See Chapter 8 for details on working with particle
attributes.
If you have programming experience, note that for vector array data types,
Maya represents the specified attribute for each particle of the object with a
single element of an array. Each element is made of three floating point
numbers. In a float array, Maya represents the specified attribute for each
particle with a vector array element that’s a floating point number.
Note
In expressions, you must type a vector in double angle brackets (<< >>).
For example, type <<3,0,5>> for a vector having 3, 0, and 5 as its left,
middle, and right component.
Expressions
find the attribute name and examine its data format.
Floating point
Boolean
Integer
A floating point attribute shows a value that includes a decimal point. Most
numerical attributes in Maya are floating point.
A Boolean attribute has a checkbox or other user interface item for turning it
on or off.
An integer attribute has no decimal point. Integer attributes are rare in
Maya.
The data type of an attribute limits what type of value you can enter for the
attribute in the Attribute Editor and in expressions. For example, because a
directional light’s Depth Map Filter Size attribute is an integer, you cannot
enter a decimal point in its text entry box or assign it a decimal quantity in
an expression.
For a floating point attribute, you can omit the decimal point. The Attribute
Editor automatically inserts a decimal point in the attribute’s text field after
you press the Enter key. For example, if you type 3 for a floating point entry,
the Attribute Editor replaces 3 with 3.0000.
Expressions
with Modify→Add Attribute, you do not define their data type either.
You can assign a value to any attribute. If the attribute is dynamic or custom,
though, you must add the attribute to the object before you can assign it a
value in an expression.
Become familiar with the purpose of an attribute by working with it in the
Attribute Editor, Channel Box, or other parts of Maya before assigning it a
value in an expression. It’s best to know the behavior you can expect from
the attribute in case you write your expression incorrectly.
Note
For rigid bodies, you can read but not write the velocity, angularVelocity,
and force attributes.
Examples
Cone.scaleY = 5.3;
This assigns 5.3 to the floating point scaleY attribute of Cone.
Ball.translateY = time;
This assigns the value of time to the floating point translateY attribute of
Ball.
Ball.scaleX = Ball.scaleY = Ball.scaleZ = 2;
This assigns 2 to the floating point scaleX, scaleY, and scaleZ attributes of
Ball. As the example shows, you can use an assignment operator several
times in a statement to set multiple attributes to the same value.
Variables
A variable is a symbolic name that stands for a constant or changing value.
There are two types of variables, predefined and custom.
Maya creates and maintains predefined variables. Custom variables are
variables you can create to store data in an expression.
Keep in mind that attributes, not variables, set object and component
behavior in Maya. You can use variables to as temporary storage for
working with the attributes.
The most common data type of variables is floating point. Integer data types
are rarely used. Booleans are commonly used in attributes, but not allowed
in variables. Vector variables are useful in expressions for particle shape
attributes.
Expressions
Animators with programming experience sometimes use string variables.
Quote marks (" ") are required with strings. See “String usage” on page 90
for details.
For a custom variable you create in an expression, you must declare the data
type as described in “Custom variables” on page 59.
Predefined variables
Maya maintains values in two predefined variables as an animation plays:
Your expressions can read, but not set, the value of time and frame. These
variables are floating point values that are useful for animating an attribute
as an animation plays.
The time updates as an animation plays. It contains the elapsed number of
seconds from the first frame to the current frame. The value increases with
the increasing frame number.
At the default animation playback rate of 24 frames per second, time has
these values, rounded to four decimal places:
0 0
1 0.0417
2 0.0833
3 0.125
24 1.0
240 10.0
frame
time = ---------------
rate
For example, if the frame rate is 24 frames/second, and the animation is at
frame 1, the elapsed time is 1 divided by 24, or 0.0417. At frame 6, the
elapsed time is 6 divided by 24, which equals 0.25.
If the frame rate is 30 frames/second and the animation is at frame 1, the
elapsed time is 1 divided by 30, which equals 0.0333. At frame 6, elapsed
time is 6 divided by 30, which equals 0.2.
Examples
Ball.translateY = time/2;
This sets the Ball’s Y translation equal to the value of time divided by 2 as
the animation plays. This make the Ball move in a Y direction as the
animation time increases.
Ball.scaleY = frame/2;
This sets the Ball’s Y scale equal to the value of frame divided by 2 as the
animation plays. The Ball scales along its Y axis as the animation frame
number increases.
Custom variables
Expressions
You can declare and use variables to store a constant or changing value.
These work like their counterparts in programming languages and
spreadsheet programs.
Though programming languages use such variables abundantly, you might
not need to use them at all in many expressions.
Declaring variables
Each custom variable name must begin with a dollar sign character ($). After
the $, you can use alphabetical, numerical, and underscore characters. You
cannot include spaces in the names.
Variable names are type case sensitive. In other words, $temp is a different
variable name than $Temp.
Examples
float $object_height;
This declares $object_height as a floating point variable.
int $counter;
This declares $counter as an integer.
vector $top_velocity;
This declares $top_position as a vector variable.
Examples
float $counter = 5.3;
This declares a floating point variable named $counter and gives it an initial
value of 5.3.
$height = 6;
This declares a floating point variable named $height and gives it an initial
value of 6. This example shows you can skip declaring the variable’s data
type. When you assign a variable a value, Maya assumes the variable is
floating point unless you specify a different data type.
$pi = 3.1415927;
$twist = $pi;
These statements show you can assign the value of one variable to another
variable. The first statement assigns 3.1415927 to $pi. The second statement
assigns the contents of $pi, 3.1415927, to $twist.
Important
If you misspell an existing declared variable name and assign it a value, a
syntax error won’t be generated for the undeclared variable. Because Maya
automatically provides a data type for an undeclared variable if it’s on the
left side of the assignment operator, the misspelled variable will be
interpreted as a newly added variable. Undeclared variables on the right
side of the assignment operator do generate error messages.
Check spellings of variables if your expression isn’t working as expected.
In the following example, the misspelling in the final statement generates
an error but not the misspelling in the statement before it:
int $start;
int $end;
int $interrupt;
$starrrt = 1;
$end = $interrupppt;
Expressions
assigning values to vector variables. Such variables are useful for working
with particle shape node attributes.
Example
global float $counter;
You can thereafter set or read the value of this variable in any other
expression in the scene.
If you create a variable with the same name in two expressions, the two
variables are separate and unrelated. For example, suppose you create a
variable named $timer in two expressions. Assigning a value to one of the
$timer variables has no effect on the other’s value.
If you declare and initialize a global variable in a single statement, you can
initialize it to a numerical constant or string only.
Examples
global float $counter = 3;
This initializes $counter to 3.
global float $counter = time;
This causes an error because time is a variable.
If you declare and initialize a global variable in a single statement, the
statement executes only when Maya compiles the expression. Maya compiles
an expression when you click the Create or Edit button in the Expression
Editor, or when you open a scene containing a previously created
expression.
Example
global float $counter = 3;
print($counter+"\n");
$counter = 1000;
print($counter+"\n");
When Maya compiles the expression, it sets $counter to 3, prints 3, sets
$counter to 1000, then prints 1000.
During playback, each execution of the expression skips the first statement,
so $counter never receives the value 3. The expression prints 1000, sets
$counter to 1000 again, and prints 1000 again.
Constants
A constant is an unchanging number or variable.
Examples
Ball.translateY = 6.1.
This statement sets Ball’s translateY attribute to the constant number 6.1.
float $pi = 3.1415927;
Ball.rotateY = $pi;
These statements set the value of Ball’s rotateY attribute to the value of the
variable $pi. The variable $pi represents the constant 3.1415927.
Arithmetic operators
Expressions
operator (%) calculates the remainder of division.
Examples
Car.translateX = time / 2.0;
This moves the Car in an X direction as the time increases in the animation.
By dividing time by 2.0, you move the object half as fast as if you used time
alone.
Car.translateX = 7 % 3;
This assigns Car.translateX the value 1, the remainder of 7 divided by 3. The
number 7 divided by 3 equals 2 with a remainder of 1.
Car.translateX = 8.8 % 4.2;
This assigns Car.translateX the value 0.4, the remainder of 8.8 divided by 4.2.
The number 8.8 divided by 4.2 equals 2 with a remainder of 0.4.
Car.translateX = 0.5 % 3;
This assigns Car.translateX the value 0.5, the remainder of 0.5 divided by 3.
The number 0.5 divided by 3 equals 0, with a remainder of 0.5.
Vectors
For operations between vector attributes and variables, the * operator
performs the dot product. The dot product multiplies corresponding
components of each vector, then adds the components to create a single
floating point number result.
For + and - operators, each component of one vector is operated on by its
counterpart component in the other vector.
For operations between a vector and an integer or floating point number,
each component of the vector is operated on by the integer or floating point
number.
Examples
Suppose you’ve initialized these vectors:
vector $A = <<1,2,3>>;
vector $B = <<2,3,4>>;
vector $C;
float $myfloat;
You then use the following statements (in different expressions, not in
sequential order):
$C = $A + $B;
This assigns $C the value << 3, 5, 7>>.
$C = $B - $A;
This assigns $C the value <<1, 1, 1>>.
$myfloat = $A * $B;
This assigns $myfloat the value (1*2) + (2*3) + (3*4), which equals 20.
Multiplying two vectors gives the dot product of the vectors.
$C = 3 * $A;
This assigns $C the value <<3, 6, 9>>. Each component of the vector is
multiplied by 3 to create a vector result.
Strings
For details on how to use the + operator with strings, see “String usage” on
page 90.
Note
Maya handles integer and Boolean attributes in an expression
mathematically as floating point numbers. After the expression executes,
Maya converts the floating point number to the proper data type.
If your expression does arithmetic on an integer or Boolean attribute and
you display the attribute’s contents in the Script Editor, you’ll see floating
point values. After the expression executes, Maya assigns an appropriate
integer or Boolean value to the attributes you set in the expression text
field.
Maya handles integer and Boolean variables within an expression
mathematically as integer and Boolean data types.
Relational operators
You’ll often use relational operators to compare the value of variables and
attributes in conditional statements. See “Conditional statements” on page
69.
Expressions
Symbol Meaning Used with these data types
Examples
if (time > 10)
Sphere.translateX = 3;
When the animation time is greater than 10 seconds of play, the expression
sets the Sphere’s translateX attribute to 3. It stays fixed in this position
thereafter. See “Conditional statements” on page 69 for details on the if
condition in this and following examples.
if (Ball.scaleY == 3)
Cone.scaleY = 6;
If Ball’s scaleY attribute is equal to 3, Maya sets Cone’s scaleY attribute to 6.
Important
Be careful to type == rather than = for the equal to operator.
For example, suppose you type if (Ball.scaleY = 3) in the previous example.
Rather than test whether Ball.scaleY is equal to 3, the statement assigns 3 to
Ball.scaleY.
Maya evaluates the assignment statement Ball.scaleY = 3 as a true
condition, so it executes Cone.scaleY = 6. This statement doesn’t cause an
error message, but it gives unintended results.
Vectors
If you use the == or != operators between two vector attributes or variables,
Maya compares the corresponding components of each vector. In contrast,
the >, >=, <, and <= operators compare the magnitude of two vectors.
Use this formula to calculate a vector’s magnitude:
2 2 2
x +y +z
Examples
vector $A = <<1,2,3>>;
vector $B = <<1,2,3>>;
if ($A == $B)
Sphere.translateX = 3;
Example 2
if ((Ball.translateX < 5) || (Ball.translateY > 10))
Ball.scaleZ = time;
This sets Ball’s scaleZ attribute to the value of time in either of two
conditions: when Ball’s translateX attribute is less than 5 or greater than 10.
Operator precedence
The precedence of operators in expressions follows:
Highest () []
! ++ - -
* / % ^
+ -
< <= > >=
== !=
&&
||
Lowest = += -= *= /=
Examples
Ball.scaleY = 8 + 2 * 4;
This assigns Ball.scaleY the value 16.
Ball.scaleY = (8 + 2) * 4;
This assigns Ball.scaleY the value 40.
Ball.scaleY = 8 + 6 - 4;
This assigns Ball.scaleY the value 10. The + executes first because it’s further
to the left in the statement than the -.
Conditional statements
Conditional statements set one attribute or variable based on the condition
of another attribute or variable. For example, you might increase the scale of
a balloon after frame 48 plays.
The if and if-else statements are the most commonly used conditional
statements in expressions.
You’ll often use relational and logical operators in conditional statements.
See page 65 and page 67 for details.
If you have programming experience, be aware you can use loop and flow
Expressions
control statements such as while and for. See “Programming features” on
page 75.
if statements
The if conditional statement has this format:
if ( condition )
statement;
If condition is true, statement executes.
Example
if (time > 3)
Ball.scaleY = 2;
This sets the scale of Ball’s scaleY attribute to 2 after the animation plays
three seconds.
if-else statements
The if-else conditional statement has the following format:
if ( condition )
statement1;
else
statement2;
If condition is true, statement1 executes. Otherwise statement2 executes.
If the animation time is less than 2 seconds, the expression sets Balloon’s
translateY attribute to 0, and sets its scaleY attribute to the value of time
multiplied by 0.6.
If animation time is greater than or equal to 2 seconds, the expression sets
Balloon’s translateY attribute to time minus 2, and sets its scaleY attribute to
1.
Important
You cannot set the same attribute in two different expressions. If you try to
do so, an error message results and your second expression has no effect.
else if statements
The else if statement works with the if-else conditional statement and has
this format:
if (condition1 )
statement1;
else if ( condition2 )
statement2;
If condition1 is true, statement1 executes and the else if statement after it is
skipped.
Expressions
If condition1 is false, the else if statement executes. If condition2 is true,
statement2 executes. If neither condition is true, neither statement executes.
You can add an else condition to the previous format as follows:
if (condition1 )
statement1;
else if ( condition2 )
statement2;
else
statement3;
If neither condition is true, statement3 executes.
Example
if (time < 3)
Ball.scaleY = 1;
else if ((time >= 3) && (time =< 6))
Ball.scaleY = 2;
else
Ball.scaleY = 3;
This sets Ball’s scaleY attribute to 1 if animation time is less than 3 seconds.
If animation time is between 3 and 6 seconds, scaleY is 2. Otherwise, when
time is greater than 6 seconds, scaleY is 3.
Note that you can add multiple else if statements and multiple statements
within braces ({ }) using this format:
if (condition1 )
{
statement;
statement;
}
else if ( condition2 )
{
statement;
statement;
}
else if ( condition3 )
{
statement;
statement;
}
else if ( condition4 )
{
statement;
statement;
}
else
{
statement;
statement;
}
Expressions
parentheses.
• When you use { and } as opening and closing braces, make sure you use
them in matching pairs:
if (time > 3)
{
Ball.rotateZ = deg_to_rad(-6 * (floor(time));
Ball.rotateY = Ball.rotateZ * 3;
}
• Enclose a vector in double angle brackets as in this example:
<<3,4,8>>
Spaces before and after the numbers and commas are optional.
• Begin any variable you use with a dollar sign ($), and do not to use spaces or
special characters other than underscores in the name. Here’s an acceptable
example:
float $my_Rotate;
$my_Rotate = 3.14;
Comments in expressions
Add comments to your expressions to explain the purpose of each statement
within. You’ll appreciate this later if you need to modify the expression.
Maya ignores comments.
Programming features
The following topics describe programming features available in
expressions. Discussion is brief and assumes you’re familiar with
programming. Most of the syntax features described work like their C
Expressions
counterparts.
• Maya’s integer data type has the same numerical range as ANSI C’s integer
data type, -2,147,483,648 to 2,147,483,648.
• Maya’s float data type has the same numerical range as ANSI C’s double
data type.
Other keywords
The return, proc, and matrix keywords are useful for writing MEL scripts,
not for expressions. Other keywords above are described throughout this
chapter.
Type keywords in lowercase letters exactly as shown. Do not name a custom
attribute with any of these keywords.
Important
Using a while, do, or for loop incorrectly might halt Maya. See “Flow
control errors” on page 88 for details.
while
A while loop has this format:
while ( condition )
{
statement;
statement;
...
}
Use condition to compare variable, attribute, or constant values. If condition is
Expressions
true, Maya executes each statement between braces. Maya then evaluates
condition again. If true, it executes each statement again. This cycle continues
until condition is false, whereupon execution resumes with the statement
after the loop.
Example
float $test = 0;
do
A do loop has this format:
do {
statement;
statement;
...
}
while (condition);
Here Maya executes each statement between braces, then evaluates condition.
The condition compares variable, attribute, or constant values. If condition is
true, each statement executes again. The loop terminates when condition is
false.
In contrast to a while loop, a do loop executes the statements in the loop at
least once. It tests the termination condition after the loop. A while loop tests
the termination condition before executing the statements in the loop.
Example
float $test = 0;
do {
print("$test equals: " +$test+"\n");
$test = $test + 1;
}
while ($test < 5);
for
A for loop has this format:
for (initialization; condition; change of condition)
{
statement;
statement;
...
}
A for loop evaluates the termination condition before executing each
statement. The condition compares variable, attribute, or constant values.
Example
float $i;
Expressions
{
print("$i equals: " +$i+"\n");
}
This expression displays the following lines in the Script Editor:
$i equals: 0
$i equals: 1
$i equals: 2
$i equals: 3
$i equals: 4
break
The break instruction exits a loop from any point within its body, bypassing
the normal termination at the loop’s beginning or end. Expression execution
resumes at the next statement after the loop. You can use a break instruction
with a while, do, or for loop.
Example
float $f = 0;
while( $f < 10 )
{
print("$f equals: "+$f+"\n");
if ( $f > 5 )
break;
$f = $f + 1;
}
This expression displays the following lines in the Script Editor:
$f equals: 0
$f equals: 1
$f equals: 2
$f equals: 3
$f equals: 4
$f equals: 5
$f equals: 6
Suppose the example didn’t have this statement:
if ($f > 5)
break;
The loop would execute ten times and display the numbers 0 through 9.
The break statement terminates the loop after $f is greater than 5. So the
expression displays only numbers 0 through 6.
continue
The continue instruction works inside loops. It forces the next iteration of the
loop to occur, skipping any statements between itself and the loop’s test
condition. The condition compares variable, attribute, or constant values.
Example
float $f = 0;
Expressions
$f equals: 7
$f equals: 8
$f equals: 9
Suppose the example didn’t have this statement:
if( $f > 5 )
continue;
The loop would display got here after each line of $f equals: n. Maya ignores
the continue instruction until $f increases to a value greater than 5.
When $f becomes 6 or greater, the continue instruction executes and skips
the remaining statement in the loop, so got here isn’t printed.
for-in
The for-in loop is a specialized for loop that simplifies manipulation of all
elements of an array. A for-in loop with an array element variable lets you
omit the initialization, condition, and change of condition components of a for
loop.
Example
string $carType[3] = {"Porsche", "Ferrari", "Fiesta"};
string $car;
for ($car in $carType)
{
print("I want a new ");
print($car + ".\n");
}
The expression displays this in the Script Editor:
I want a new Porsche.
I want a new Ferrari.
I want a new Fiesta.
The loop executes three times, once for each array element in $carType.
The first loop execution copies array element $carType[0] into $car, then
prints, “I want a new Porsche.” Array element $carType[0] is Porsche.
The second loop execution copies $carType[1] into $car, then prints the
second line shown. The third execution copies $carType[2] into $car, then
prints the third line shown.
When the for-in statement finishes reading all array elements, the loop
terminates.
switch
A switch instruction executes one of several groups of statements based on a
control value. The control value can be a variable value or an attribute other
than an array (per particle) attribute. The format follows:
switch (control-value)
{
case value1:
statement;
statement;
...
break;
case value2:
statement;
statement;
...
break;
case value3:
statement;
statement;
...
break;
...
default:
statement;
Expressions
statement;
...
break;
}
The switch executes with a variable control-value. If the variable contents
match value1, value2, or another value in the switch, the statements under the
associated case statement execute. The control-value can be an int, float,
string, or vector.
Be careful if you use a float control-value. Because of the way floating point
arithmetic rounds numerals, a case value might fail to match a control-value
as you expect.
A break statement within a switch causes execution to skip subsequent case
statement groups within the switch instruction.
Expressions
Note that you can make more than one case statement execute the same
statements:
int $argo = rand(4);
switch ($argo)
{
case 0:
case 1:
print("Food\n"); // Runs if $argo is 0 or 1
case 2:
case 3:
print("Fight\n");// Runs if $argo is 2 or 3
break;
}
This works like the preceding expression, except that a match of 0 or 1
displays Food and Fight, and a match of 2 or 3 displays Fight.
Example
You can use the default keyword to make a block of statements execute when
none of the case values match the control value label. Generally, you put this
label after all the case statements, though you can put it anywhere in the
switch statement.
If the switch has no default label and none of the case values match the
control value, the switch does nothing.
vector $mgb = <<1,1,0>>;
switch ($mgb)
{
case <<0,1,1>>:
print("Who?\n");// Runs if $mgb is <<0,1,1>>
break;
case <<1,0,1>>:
print("What?\n");//Runs if $mgb is <<1,0,1>>
break;
default:
print("Why?\n"); // Executes if $mgb is not
break; // <<0,1,1>> or <<1,0,1>>
}
The expression executes the default case, which displays the following line
in the Script Editor:
Why?
?: operator
The ?: operator lets you write a shorthand if-else statement to set an attribute
or variable in one statement. Because of its cryptic appearance, many
programming style experts suggest not using it.
Here’s its format:
attribute = condition? statement1: statement2;
The condition compares variable, attribute, or constant values. If condition is
true, Maya evaluates statement1 and assigns its value to attribute. (You can
also assign the statement’s value to a variable.)
Maya evaluates either statement1 or statement2, never both.
You can optionally enclose statement1 and statement2 in parentheses to make
the expression easier to read.
Example
Balloon.scaleY = (time < 2) ? time / 2: time * 2;
This statement sets Balloon’s scaleY attribute to time divided by 2 if time is
less than 2, and time multiplied by 2 if time is greater than or equal to 2. This
causes the scaleY attribute to increase slower for the first two seconds than
after two seconds.
This is the same as the following if-else statement:
if (time < 2)
Balloon.scaleY = time / 2;
else
Balloon.scaleY = time * 2;
Use this format because it’s easier to read.
Important
If you use an integer value as statement1 and a floating point value as
statement2, the ?: operator truncates the floating point value of statement2 to
an integer.
In the expression Balloon.scaleY = (time < 2) ? 0: time;, for example, 0 is an
integer, and time is a floating point value. When time is 2 seconds or more,
Maya sets Balloon’s scaleY attribute to the integer value of time.
Expressions
Because Maya sets scaleY to the integer value of time (without the decimal
part), scaleY jumps in one-second increments at time 2, 3, 4, and so on.
If you have problems using the ?: operator, use an if-else statement instead.
! operator
You can use the not logical operator (!) with integer, float, and vector data
types.
For vector values, ! is true only when the vector magnitude is 0. A vector’s
magnitude is the value resulting from this equation:
2 2 2
x +y +z
Examples
if (!$count)
Ball.scaleY = 2;
The !$count condition is true only if $count is 0. If true, Ball.scaleY is set to 2.
vector $myvector = <<0,0,0>>;
if (!$myvector)
Ball.scaleY = 2;
Because the magnitude of $myvector is 0, the !$myvector condition is true
and Ball.scaleY is set to 2.
Example 1
Suppose you create an object named Balloon and decide to use a while loop
to increase its Y scaling after three seconds of animation play.
while (time > 3)
Balloon.scaleY = time;
Though you might think this expression sets Balloon’s scaleY attribute to the
increasing value of time after the animation time exceeds 3 seconds, it
actually halts Maya operation as soon as time exceeds 3. At that moment, the
while condition is true, so the while loop statement Balloon.scaleY = time
executes repeatedly and endlessly.
Even though a statement sets an attribute within an expression, Maya
updates the attribute only after the expression finishes executing. Because
the expression never finishes executing, Maya halts.
Unless you change Balloon.scaleY within the while loop to a value less than
or equal to 3, the statement executes infinitely.
To get the desired result without halting Maya, use this expression:
if (time > 3)
Balloon.scaleY = time;
Example 2
Suppose you create objects named Cone and Ball, then use a while statement
to link the Ball’s translateY attribute to the Cone’s translateY attribute:
while (Cone.translateY > 0)
Ball.translateY = Cone.translateY;
At first glance, the expression seems to set Ball’s translateY position to the
value of the Cone’s translateY position whenever Cone’s translateY is greater
than 0.
In fact, the expression halts Maya as soon as you translate the Cone to a Y
position greater than 0. At that moment, the while condition is true, so the
while loop statement Ball.translateY = Cone.translateY executes endlessly.
Nothing you do in the user interface can change the Cone’s translateY
position. It stays at translateY value of 0.
Unless you change Cone.translateY within the while loop to a value less
than or equal to 0, the statement executes infinitely.
To get the desired result without halting Maya, use this expression:
Expressions
if (Cone.translateY > 0)
Ball.translateY = Cone.translateY;
Example
float $x = cosd(90);
if ($x == 0)
print("This equals 0.\n");
else
print("This doesn’t equal 0.\n");
String usage
A string is a sequence of alphabetical, numerical, and special characters. You
can display strings in the Script Editor, for example, to check the contents of
attributes or variables.
You can also create strings in the Expression Editor to execute MEL
commands in an expression. See Chapter 7 for details.
Guidelines for using strings follow:
• Enclose a literal string with double quotes as in this example:
print("asteroid2");
This displays the following text:
asteroid2
• You can use the + operator to concatenate strings as in this example:
print("Ball’s scaleY attribute equals: " + Ball.scaleY);
Expressions
vector $i = vector ("<<1,2,3>>");
• You can execute a MEL command in an expression statement. See
“Executing MEL commands in an expression” in Chapter 7.
The following table shows the shorthand operators and the valid data types
for each. The shorthand operators work like their counterparts in C.
%= integer, float
Example
$counter += 1;
This adds 1 to $counter each time the statement executes.
Examples
float $eel = 32.3;
float $crab = $eel++; // $crab = 32.3; $eel = 33.3;
$crab = $eel--; // $crab = 33.3; $eel = 32.3;
$crab = --$eel; // $crab = 31.3; $eel = 31.3;
$crab = ++$eel; // $crab = 32.3; $eel = 32.3;
Important
To avoid unexpected results, do not use more than one shortcut increment
or decrement operator on the same variable in the same statement. The
evaluation order of the operators is unpredictable.
Arrays
You can create arrays of float, vector, integer, or string values. You can clear
an array using a clear function. You can find the size of an array with the
size function. See “Array functions” in Chapter 9 for details.
When you assign a value in an array, Maya reserves memory for all
elements less than that number. This means you can exceed the capacity of
your computer with a single array declaration. For example, do not use a
statement like this:
Expressions
$newarray[12312323123] = 1;
The second statement makes the array contain 1501 elements and assigns
element 1500 the value 3. The third statement expands the array to 2001
elements and assigns element 2000 the value 5.
The for loop stops executing after $i becomes equal to 10. Then the final
print statement displays the number of elements of the initialized array, 10.
The array increased in size as you assigned values to its elements.
Example
if (Monster.visibility == on)
Lance.scaleY = time / 3;
This causes Lance’s scaleY attribute to increase only if Monster’s visibility
attribute is on. The on represents 1.
print(3 + on);
This displays 4 in the Script Editor. Again, on represents the value 1.
Expressions
syntax errors and logic errors. Syntax errors include mistakes in spelling,
incomplete attribute names, omitted semicolons, and other oversights that
prevent the expression from compiling and executing. For syntax errors,
Maya explains the error in a message to the Script Editor.
Logic errors are mistakes in your reasoning that cause unexpected animation
results. The syntax of your expression is valid, but errors in your logic
prevent Maya from doing what you intended. In the worst cases, Maya
might halt operation because your statements lock it into a permanent loop.
Because Maya can’t detect logic errors, it can’t display error messages. As
such, these errors are harder to find and require more analysis to solve. To
resolve logic errors, it’s often helpful to display the contents of relevant
attributes and variables. See “Displaying attribute and variable contents” in
Chapter 7.
You’ll often need to scroll or increase the size of the Script Editor to see an
entire message.
When the Script Editor displays a syntax error, the response area of the
Command Line displays the same error with a red background.
Before clicking the Create or Edit button to create an expression, you might
want to select Edit→Clear History in the Script Editor to remove previous
messages in the window. This makes it easier to see when a new error
message appears.
Expressions
• set driven key
• constraint
• motion path
• another expression
• any other direct connection
More than one attribute name matches. Must use unique path
name: Ball.tx.
You used an object.attribute name that exists in two or more parent objects.
Two objects in a scene can have the same object name if they have different
parent objects.
For example, a scene might have a child of GroupA named Ball.tx and a
different child of GroupB named Ball.tx. If you write a statement such as
“Ball.tx = time;”, Maya won’t know which Ball.tx to set.
To eliminate the error in this example, you must enter the full pathname of
the attribute as GroupA|Ball.tx. The pipe symbol (|) specifies that the object
to its left is the parent of the object on the right.
Cannot set 'time' or 'frame'
You can read the value of the predefined time and frame variables, but you
cannot set them.
Attributes must be of float, integer, or boolean types:
Ball.worldMatrix
You tried to set or read the value of an attribute that was a string or matrix
type. For instance, you might have tried to use an attribute named translate
rather than translateX, translateY, or translateZ attribute.
In the error message above, worldMatrix is an attribute that exists for
transforms, but you can’t use it. It’s for Maya’s internal use.
Cannot divide by zero
You tried to divide by an attribute or variable that equals 0. This typically
happens in an expression statement that divides by an object’s translateX,
translateY, or translateZ attribute when the Snap to grids button is on and
you drag the object to past the X-, Y- or Z-axis. When Snap to grids is on, the
translateX, translateY, or translateZ attribute becomes exactly equal to 0 at
the point where you drag the object across the axis.
To prevent this error, turn Snap to grids off. With snapping off, the attribute
is unlikely to become exactly 0 as you drag across the axis.
Note
If you compile an expression for a particle shape node and see the same
error message once for each particle in the object, it’s likely that some
attribute name, variable, or function is undefined or misspelled.
The Expression Editor offers convenient techniques for editing the text of
expressions. There are filters that help you search for expressions you
previously created, as well as techniques for entering and modifying the text
of an expression.
Expressions
• “Editing an expression in the text field” on page 105
• “Editing an expression with a text editor” on page 106
• “Creating a new expression” on page 111
• “Deleting an expression” on page 112
• “Using attribute names in expressions” on page 112
Finding expressions
After you’ve created an expression, you might decide later to alter it to
create a different animation result. To edit an expression, you display it in
the Expression Editor. The following sections describe how to find and
display an expression for editing.
List of expressions
Note
For a particle shape node, you can create a creation expression, a runtime
expression, or both. Both expressions are listed under a single name—the
name of the particle shape node. You can’t name or rename such
expressions.
To find such expressions, look for the particle shape node’s name in the
Expressions list.
Click the appropriate Runtime or Creation checkbox to display the desired
expression.
Object name
Object’s attributes
4 For an object other than a particle shape node, click the name of the attribute
Expressions
controlled by the expression.
If you’ve forgotten the name of the attribute controlled by the expression,
choose Attribute Filter→Connected to Expressions. The Attributes list
displays only the attributes controlled by expressions for the selected object.
Click each attribute in the Attributes list until you see the desired expression
in the expression text field.
You can’t write a different expression for each attribute of a particle shape as
you can for other types of objects. Because you can write only one creation
expression and one runtime expression per particle shape, you don’t need to
select an attribute from the Expression Editor’s Attributes list. See
“Understanding particle expressions” on page 148 for details on particle
expressions.
Note
The Attributes list shows only unlocked, keyable attributes. You can
choose whether an attribute is keyable or locked with View→Object→
Editors→Channel Control.
To write an expression for any nonkeyable attribute not shown in the list,
enter object.attribute name in the Selected Obj & Attr text box.
Example
Suppose you’ve written an expression that controls the rotateZ attribute of a
spotlight transform node named Searchlight. Do this to find the expression:
1 Choose Select Filter→By Object/Attribute name.
2 Select Object Filter→Transforms.
Note that you don’t select Object Filter→Lights in this example. The rotateZ
attribute is an attribute of a light’s transform node, not of the light object
itself.
3 Choose Attribute Filter→Connected to Expressions.
4 Select the object Searchlight from the Objects list.
Expressions list
Expressions
Using the Objects and Attributes list
The objects listed in the Objects list depend on which entry you’ve selected
from the Object Filter menu. If you select Object Filter→Lights, for
instance, all lights in the scene appear in the list.
The appropriate attributes of the object selected in the Objects list appear in
the Attributes list. For example, if spotLightShape1 is selected in the Objects
list, the attributes of spotLightShape1 appear in the list.
When searching for an expression to edit, you can click an object and
attribute from this list to find and display an expression that affects the
chosen attribute. You can edit the displayed expression in the expression text
field.
For a particle shape node, you don’t need to select an attribute from the
Attributes list. You can create only one creation expression and one runtime
expression per particle shape node. The same expression appears for each
attribute.
When you create a new expression, you can click an object from this list to
choose the default object to which the expression applies.
When you select the default object in the Expression Editor, you can skip
omit the object name and period that’s part of a full attribute name (see
“Omitting an object name in expressions” on page 115.)
Important
If you close the Expression Editor window without successfully compiling
an expression with the Create or Edit button, Maya discards any editing
changes you’ve made to the expression.
Expressions
Deleting and copying text
To delete text:
1 Drag the mouse to select the text.
2 Press your keyboard’s Backspace key to delete it.
Important
To erase an expression and make sure its previous contents no longer
control an attribute, click the Edit button after clicking the Clear button.
There is no file on disk you can edit independently of the Expression Editor.
When you use the text editor through the Expression Editor, you’re working
with a temporary file that’s linked to the expression stored in the scene. You
can, however, read an independent text file containing expression text into
the temporary file.
If you save an expression without specifying a filename, Maya reads the
saved expression and stores it with the scene. You’ll see it dimmed in the
expression text field while you’re working with the text editor.
When you close the text editor, the expression text field entry no longer is
dim. The text expression field becomes active after you close the text editor.
If you quit the text editor without saving the expression, Maya does nothing.
Because the expression hasn’t changed, Maya’s copy of the expression
doesn’t need to change either.
Tip
You can use a text editor to save an expression to a filename in the
directory of your choice. This gives you a way to archive an expression you
want to use in a different scene.
Expressions
By default, you can start one of these editors from the Editor menu in the
Expressions Editor:
• jot
• vi
• vim
• xemacs
To run a different editor, see “Using an editor not listed in the Editor menu”
on page 109.
The editor’s title bar shows a filename that’s temporarily created while you
work on the expression. When you write or save the file, its contents are
copied to the Maya scene containing the expression.
The expression text field is inactive while the text editor is open. You can
optionally close the Expression Editor window.
If you single-click the name of an object, attribute, or expression, the text
editor doesn’t appear. You can single-click to browse the contents in the
expression text field without opening a text editor.
If you double-click an attribute that’s already been assigned a value in an
expression, the expression that controls that attribute appears in the text
editor. For nonparticle expressions, you can assign to any attribute in the
scene, not just to the double-clicked attribute. In fact, you don’t even need to
work with the double-clicked attribute at all.
If you double-click an attribute that has not yet been assigned a value, the
text editor appears with no contents. If you double-click that attribute again,
a new instance of the editor appears. After you assign a value to an attribute
in an expression, you can start the editor only once for the attribute.
3 Create or edit the expression with the editor.
4 Save the file.
5 Confirm that the Expression Editor detected no syntax errors.
6 Quit the editor.
Note
If you’ve created a UNIX command alias for jot, vi, vim, or xemacs, the
Expression Editor tries to launch this command. If the arguments provided
in the command alias are unusable by the Expression Editor, the editor
might operate unexpectedly or fail to launch.
Avoid using an alias to customize your editor’s operation settings. Do the
steps in “Changing an editor’s operation settings” on page 110.
Expressions
make the WINEDITOR setting display the editor in a shell.
2 Log out and log into your user account.
3 Restart Maya.
4 Choose Other from the Editor pull-down menu.
5 Double-click an object name, expression name, or attribute name from the
Selection list.
The editor appears.
6 Create or edit the expression with the editor.
7 Save the file.
8 Confirm that the Expression Editor detected no syntax errors.
9 Quit the editor.
Important
If you’ve specified a text editor through Options→UI Preferences or with
the Expression Editor’s Editor menu, starting the Expression Editor from
the Channel Box or Attribute Editor displays the text editor instead of the
Expression Editor.
Expressions
Note the text editor appears when you click the New Expression button.
When you create the expression, the Expression Editor associates the object
name with the expression. This means you can narrow your search for the
expression using the object’s name in addition to the expression name.
You do not need to select an attribute in the Attributes list. You can associate
the expression with an object only.
For a particle shape node, you don’t need to select an attribute, as you can
create only one creation expression and one runtime expression per particle
shape. For nonparticle shape objects, you can create one expression per
attribute.
Deleting an expression
If you want to stop an expression from controlling attributes, you can delete
the expression.
To delete an expression:
1 Display it in the Expression Editor.
2 Click the Delete button.
Example
In place of this:
Ball.translateY = time;
you can type this:
Ball.ty = time;
Each attribute has at least one acceptable abbreviation. Here are some
commonly used attribute name abbreviations for several types of object
transform nodes:
translateX tx
translateY ty
translateZ tz
Expressions
rotateX rx
rotateY ry
rotateZ rz
scaleX sx
scaleY sy
scaleZ sz
visibility v
Common English equivalents for the long attribute names appear in the
Channel Box by default. These names are different than the names you must
use in the expression text field.
If you use the long attribute name, use the name that appears in the
Attributes list of the Expression Editor. Do not use the common English
language equivalents displayed in the Channel Box.
3 From the Channels menu at the top of the Channel Box, select
Channel Names→Short.
The abbreviated attribute names replace the common English attribute
names in the Channel Box.
Note
After you click Create or Edit to compile an expression, Maya converts all
attribute abbreviations in the expression to the full attribute name.
Example
Suppose you’ve selected Ball as the Default Object.
In place of this:
Ball.translateY = time;
you can type this:
Expressions
translateY = time;
Maya interprets translateY as belonging to Ball, the object listed in the
Default Object text box of the Expression Editor.
Example
Suppose you’ve selected Ball as the Default Object.
In place of this:
Ball.translateY = time;
you can type this:
ty = time;
Maya interprets ty as being the translateY attribute of Ball, the object listed
in the Default Object text box of the Expression Editor.
Attributes of other objects must be spelled out with the full object and
attribute name.
Expressions
goal and springs. As its points move
below the floor, an expression
assigns them a goal weight of 0.
The cube appears to melt as it
passes through the floor.
Rob Tesdahl
Example
Suppose you’ve given a NURBS sphere named Planet a circular, orbiting
motion in the XY plane with this expression:
Planet.tx = sin(time);
Planet.ty = cos(time);
Expressions
Planet orbits the origin at a radius of 1 unit.
In the following steps, you’ll create a custom attribute named distance to
increase the radius of Planet’s orbit over time.
Note
The small balls in the preceding figure show the circular path of Planet.
They’re in the figure only to help you visualize the motion. They aren’t
part of the animation or expression.
3 In the Add Attribute window, enter distance in the Attribute Name text box.
4 Make sure Make attribute keyable is on.
5 Set Data Type to Float, and Attribute Type to Scalar.
6 Set Minimum to 1, Maximum to 10, and Default to 4.
Minimum and Maximum set the lowest and highest values you can enter
for the attribute in the Attribute Editor or Channel Box.
Default sets the default value displayed for the attribute.
An expression isn’t bound by the Minimum and Maximum values. The
attribute receives whatever value you assign it in the expression.
The expression can read the Default value or any other value you set in the
Attribute Editor or Channel Box.
7 Click Add to add the attribute, then close the Add Attribute window.
The distance attribute appears in the Attributes list of the Expression Editor
for Planet. You can now set or read the value of the attribute in any
expression.
8 Edit the expression to this:
Planet.tx = distance * sin(time);
Planet.ty = distance * cos(time);
Multiplying the sin(time) and the cos(time) by the distance attribute makes
Planet circle the origin at a distance specified by the value of the distance
attribute. See Chapter 9 for details on the sin and cos functions.
Expressions
Because you gave the distance attribute a default value of 4 when you added
it to Planet, playing the animation makes Planet circle the origin at a distance
of 4 grid units from the origin.
You can make the expression control the distance attribute over time.
9 Edit the expression to this:
distance = time;
Planet.tx = distance * sin(time);
Planet.ty = distance * cos(time);
By setting distance to the value of time, Planet’s orbiting distance increases
as playback time increases. Planet moves in a steady outward spiral as the
animation plays.
Tip
If an expression controls an attribute and you want to control it with
keyframes instead, delete all statements that assign values to the attribute,
then click the Edit button. Use the Channel Box to reset the attribute’s
value to an initial value, then set keyframes as desired.
If keyframes control an attribute and you want to control it with an
expression instead, click the attribute’s text box in the Channel Box, then
choose Channels→Delete Selected. Assign values to the attribute name in
an expression as desired.
Reproducing randomness
If you execute the rand, sphrand, and gauss functions repeatedly in an
expression, Maya returns a sequence of random numbers. (See “Random
number functions” on page 239 for details on these functions.) Each time you
rewind and play your animation, the sequence of random numbers is
different. Often, you’ll want to generate a sequence of random numbers that
repeats each time your animation plays.
For instance, suppose you use the rand function to assign a random radius
to each particle in a stream of emitted particles rendered as Spheres. By
default, Maya gives the particles a different sequence of random radius
values each time your animation plays.
Expressions
To create the same radius values each time the animation plays, you can use
the seed function in an expression before the rand, sphrand, or gauss
functions execute. There’s no need to execute the seed function more than
once per animation unless you need to generate several different repeating
sequences of random numbers as your animation plays.
Important
When you set a seed value in an expression or MEL script, the seed value
affects the rand, sphrand, and gauss functions in other expressions and
MEL scripts. Such functions are affected by this seed value in all scenes
you open subsequently in the current work session.
This seed value is unrelated to the Seed option available through
Settings→Dynamics Controller in the Dynamics menus. The seed function
therefore doesn’t affect randomness created with dynamics.
Example
Suppose you use the rand function to position several marbles at random
translateX positions in your scene at frame 1:
if (frame == 1)
{
marble1.tx = rand(-10,10);
marble2.tx = rand(-10,10);
marble3.tx = rand(-10,10);
marble4.tx = rand(-10,10);
}
The rand(-10,10) returns a random number between -10 and 10 each time it
executes. When you rewind the animation to frame 1, Maya might assign
these values to the translateX attributes of the marbles:
Attribute Value
marble1.tx 2.922
marble2.tx 5.963
marble3.tx -4.819
marble4.tx 7.186
The next time you rewind the animation to frame 1, each marble’s translateX
attribute receives a different random value. Maya might assign these values:
Attribute Value
marble1.tx -3.972
marble2.tx 9.108
marble3.tx -7.244
marble4.tx -3.065
You might prefer the marbles’ translateX values to stay the same when you
rewind, for instance, so you can composite the marbles correctly among a
Expressions
foggy backdrop.
You can use the seed function to keep the sequence of random values
returned by the rand function consistent when you rewind the animation.
if (frame == 1)
{
seed(10);
marble1.tx = rand(-10,10);
marble2.tx = rand(-10,10);
marble3.tx = rand(-10,10);
marble4.tx = rand(-10,10);
}
By setting the seed value to an arbitrary number, for instance, 10, the
subsequent executions of the rand function return a repeating sequence of
random numbers.
When you rewind the animation the first time, Maya might assign these
values to the translateX attributes of the marbles:
Attribute Value
marble1.tx 8.020
marble2.tx -2.973
marble3.tx -7.709
marble4.tx 0.741
Each time you rewind the animation thereafter, Maya assigns these same
values to the translateX attributes of the marbles. The marbles don’t move.
Each time a statement sets the seed value to 10, the subsequent executions of
the rand function return numbers from the sequence starting at the
beginning number. In other words, resetting the seed value to 10 restarts the
random number generation process to the first value in the sequence.
Suppose you alter the expression to this:
if (frame == 1)
{
seed(10);
}
marble1.tx = rand(-10,10);
marble2.tx = rand(-10,10);
marble3.tx = rand(-10,10);
marble4.tx = rand(-10,10);
When you rewind the animation to frame 1, the expression sets the seed to
10. Maya assigns values to the marbles’ translateX attributes as in the
previous expression.
Because the expression doesn’t set the seed value in frames other than frame
1, playing the animation causes the rand function to return a new, yet
repeating, sequence of random numbers each frame. If you play the
animation several times, the translateX values will constantly change during
animation, but the sequence of values will be identical each time you play
the animation.
You can assign the seed a different value to generate a different sequence of
returned values. See “seed” on page 246 for details.
Expressions
Example
Suppose you’ve selected degrees from the Angular menu in the Units
folder. You then write this expression for an object named Ball:
Ball.rotateZ = 10;
Maya reads the 10 as being 10 degrees, then converts the value to the
appropriate number of radians to make the assignment to Ball’s rotateZ
attribute. The conversion happens automatically. From your standpoint,
Maya is simply rotating Ball 10 degrees.
In nonparticle expressions, these automatic conversions affect Maya
performance. Because the expression executes slower, Maya slows when you
play, rewind, or otherwise change the animation time. Saving, opening, and
other file operations on the scene containing the expression are also slower.
To boost Maya performance, you can turn off conversion to internal units. If
you do so, you must convert units in expression statements.
Example
Suppose, in the Units folder, you’ve set Linear units to millimeters and
Angular units to degrees. You then write the following expression:
Ball.translateX = 5;
Ball.rotateZ = 10;
All causes Maya to read 5 as millimeters and 10 as degrees.
None causes Maya to read 5 as centimeters and 10 as radians.
Angular causes Maya to read 5 as centimeters and 10 as degrees.
Examples
Suppose, in the Units folder, you’ve set Linear units to millimeters and
Angular units to degrees.
In the Expression Editor you set the Convert Units option to None and enter
this expression:
Ball.translateX = 5;
Ball.rotateZ = 10;
None causes Maya to read 5 as centimeters and 10 as radians, which is not
the result you’re seeking.
To assign 5 millimeters to Ball’s translateX attribute, you must convert 5 to
the appropriate number of centimeters. To assign 10 degrees to Ball’s rotateZ
attribute, you must convert 10 to the appropriate number of radians.
The following statements do this:
Ball.translateX = 5.0 / 10.0;
Ball.rotateZ = 10.0 / 57.3;
There are 10 millimeters per centimeter. In other words, a millimeter is a
centimeter divided by 10. So 5 millimeters equals 5 centimeters divided by
10. You therefore use the operation 5.0 / 10.0.
Important
Expressions
When you divide floating point attributes or variables, enter the floating
point value 5.0 for an even number such as 5. This ensures that the division
works as expected. For more details, see the note in “Using mixed data
types with arithmetic operators” on page 145.
There are 57.3 degrees per radian. In other words, a degree is a radian
divided by 57.3. So 10 degrees equals 10 radians divided by 57.3. You
therefore use the value 10.0 / 57.3.
If you need a more precise conversion to radians, divide a degree by
57.29578 instead of 57.3. You can instead use the deg_to_rad function as
follows:
Ball.rotateZ = deg_to_rad(10.0);
The deg_to_rad function converts 10.0 degrees to a precise radian
equivalent. See “deg_to_rad” on page 234 for details.
Turning off unit conversion affects only expressions. It doesn’t affect other
Maya commands, options, or displays. For instance, the preceding example
expression assigns centimeters to translateX and radians to rotateZ. The
Channel Box still displays values for these attributes in millimeters and
degrees. It displays values in whatever units you choose in the Units folder
of the General Preferences window.
Note that you can’t turn off unit conversion for particle shape node
expressions. Maya handles unit conversion differently for such expressions
with little impact on performance.
Example
global float $BallHeight = 5;
print($BallHeight+"\n");
nurbsSphere1.tx = rand(1);
print(nurbsSphere1.tx+"\n");
The first statement declares and assigns a value to the variable $BallHeight,
which is not an attribute. The next statement prints the $BallHeight but
assigns no value to an attribute.
The next statement assigns an attribute a value, but the value is generated by
the random number function rand. This function doesn’t read an attribute
value. For details on the rand function, see “rand” on page 243.
The last statement reads and prints the value of an attribute, but doesn’t
assign a value to an attribute.
None of these actions causes the expression to execute when Always
Evaluate is off.
Always Evaluate affects only the expression you’re creating or editing. You
can turn it on for one expression and off for another.
Expressions
For most animations, expressions execute regardless of whether Always
Evaluate is on. If in doubt, leave it on.
The attribute doesn’t return to the value it had before the expression set it.
To return the attribute to its original value, use the Channel Box or Attribute
Editor to set the attribute.
Disconnecting an attribute
If you disconnect an attribute from an expression, the expression no longer
reads or set its value. You might want to disconnect an attribute, for
example, so you can keyframe the attribute rather than control it with an
expression.
These actions disconnect an attribute from an expression:
• Delete from the scene an object with an attribute that exists in the
expression.
• Use the Window→General Editors→Connection Editor to disconnect the
attribute from the expression.
• Use the MEL disconnectAttr command.
• Use the MEL choice command.
Tip
The MEL choice command lets you control an attribute alternately with two
or more techniques in different frames. For example, you can keyframe an
attribute for frames 1-48, control it with an expression for frames 48-96, and
control it with a motion path for subsequent frames.
Example
Suppose your scene has two objects, Ball and Cone, and you’ve written this
expression:
Ball.translateX = Cone.translateX;
Ball.translateY = Cone.translateY;
Ball.translateZ = Cone.translateZ;
Expressions
Ball.translateZ the value 0.
Note that if you disconnect an attribute from an expression but the attribute
still exists in the scene, the attribute keeps its value from the last time the
expression executed and set its value.
Example
Suppose you’ve written these statements among others:
Ball.translateX = Cone.translateX;
Ball.translateY = Cone.translateY;
Ball.translateZ = Cone.translateZ;
If you delete Ball from the scene, Ball.translateX, Ball.translateY, and
Ball.translateZ attributes no longer exist. The expression can no longer
assign Cone’s translateX, translateY, and translateZ values to the
corresponding Ball attributes.
Note
If an expression assigns values to the attributes of only one object, deleting
the object deletes the expression also. If your expression assigns values to
attributes of several object attributes, deleting all those objects deletes the
expression.
To avoid deleting the expression in the preceding example, you would
need have some statement that sets an attribute of an object other than the
deleted Ball. For example, you might include this statement:
Cone.visibility = 1;
Example 1
Suppose you have these statements among others in an expression named
HorseController:
WhiteHorse.translateX = Car.translateX;
BlackHorse.translateX = Car.translateX;
BrownHorse.translateX = Car.translateX;
Deleting the Car and reloading the expression shows this:
WhiteHorse.translateX = .I[0];
BlackHorse.translateX = .I[0];
Expressions
BrownHorse.translateX = .I[0];
.I[0] is the symbolic placeholder for what was the Car.translateX attribute.
You can connect a different attribute to this placeholder to assign its contents
to the translateX attributes of WhiteHorse, BlackHorse, and BrownHorse.
Suppose you want to control these attributes with the translateX attribute of
an object named Cow. You can enter the following MEL command at the
Command Line:
connectAttr Cow.tx HorseController.input[0]
This command connects the attribute Cow.tx to the expression’s input[0].
The expression is named HorseController. The input[0] is abbreviated as .I[0]
in the expression. You can see the spelled-out input name input[0] in the
Graph→Up and Downstream Connections display of the Hypergraph.
Reloading the expression shows the new attribute connection:
WhiteHorse.translateX = Cow.translateX;
BlackHorse.translateX = Cow.translateX;
BrownHorse.translateX = Cow.translateX;
Example 2
You can also reconnect an expression’s output with the connectAttr
command. Suppose you have these statements among others in an
expression named HorseController:
WhiteHorse.translateX = Car.translateX;
BlackHorse.translateX = Car.translateX;
BrownHorse.translateX = Car.translateX;
Deleting the BrownHorse object and reloading the expression displays this:
WhiteHorse.translateX = Car.translateX;
BlackHorse.translateX = Car.translateX;
.O[2] = Car.translateX;
.O[2] is the symbolic placeholder for what was the BrownHorse.translateX
attribute. It received the placeholder .O[2] because it’s the third output from
the expression. (The first and second outputs from the expression are .O[0]
and .O[1] .) You can connect a different object attribute to this placeholder to
control it with the value in Car.translateX, as shown in the third statement.
Suppose you want to control the attribute of a new object named
RedHorse.translateX with the Car.translateX value. You can enter the
following MEL command in the Command Line:
connectAttr HorseController.output[2] RedHorse.tx
This command connects the HorseController expression’s output[2] to the
attribute RedHorse.tx. The output[2] is abbreviated .O[2] in the expression.
Reloading the expression shows the new attribute connection:
WhiteHorse.translateX = Cow.translateX;
BlackHorse.translateX = Cow.translateX;
RedHorse.translateX = Cow.translateX;
Renaming an object
If you rename an object whose attributes were used in an expression, the
Expression Editor continues to read or set the attributes. Maya doesn’t
disconnect the attribute from the expression. The Expression Editor converts
to the new name of the object the next time you click the Reload button in
the Expression Editor.
Note
When you reload an expression, the Expression Editor converts any short
attribute names to their long attribute name equivalents. For example, if
you originally type the attribute name Ball.ty, reloading the expression
renames it as Ball.translateY.
Expressions
You can execute MEL commands in an expression with several techniques:
• MEL command alone in a statement
• MEL command within left-hand single quote marks
• MEL command used as an argument to an eval function
• MEL procedure call to a procedure in a MEL script
The following topics explain the techniques. See Using MEL for details on
MEL.
Example
select -cl;
This example shows the use of a MEL command alone. The statement
executes exactly as it would in the Script Editor, except no command output
appears in the Script Editor.
Example
string $a[];
$a = ‘ls -lights‘;
print($a);
The first statement defines an array named $a. The second statement
executes the MEL command within quotes, then assigns the command’s
output to array $a. The third statement displays the contents of $a to the
Script Editor as follows:
ambientLightShape1
directionalLightShape1
Example
string $mycommand = "sphere";
eval($mycommand+" -r 5");
The first statement assigns the string sphere to the variable $mycommand.
The second statement appends -r 5 to sphere and executes the complete
command sphere -r 5. This creates a sphere with a radius of 5 grid units.
See “eval” on page 259 for more details.
Example
Suppose, in your Maya scripts directory, you’ve created a MEL script file
named randspot.mel with the following contents:
global proc string randspot()
{
Expressions
string $mycommand;
if (rand(2) < 1)
$mycommand = "particle -p "+ sphrand(10);
else
$mycommand = "sphere -p "+ sphrand(10);
return $mycommand;
}
Further suppose you’ve created this expression:
string $randcommand = randspot();
eval($randcommand);
When you rewind or play a frame in the animation, the expression executes.
The first expression statement executes the randspot procedure in the
randspot.mel script file. In the randspot procedure, the rand(2) part of the if-
else statement generates a random floating point value between 0 and 2,
then compares its value to 1. For details on the rand function, see “rand” on
page 243.
If the rand(2) function returns a value less than 1, the if statement assigns a
MEL command string such as particle -p -1.356 5.983 8.458 to $mycommand.
The + sphrand(10) part of the statement appends to sphere -p the three floating
point components of a randomly generated vector.
Though sphrand(10) returns a vector, Maya converts the vector to a string
upon assigning it to the string $mycommand. For details on the sphrand
function, see “sphrand” on page 244.
The converted string contains no double angle brackets or commas, but does
contain a space character between the floating point components. A space
between the floating point components is required syntax for the MEL
particle command as used above.
If the rand(2) function returns a value greater than 1, $mycommand receives
a MEL command string such as sphere -p 4.926 -2.589 1.274.
The procedure finishes executing and passes the value of $mycommand
back to the expression’s calling procedure randspot( ). This assigns the
command string to the variable $randcommand.
The eval function executes the command string in $randcommand. For
example, if the statement executes particle -p -1.356 5.983 8.458, it creates a
particle with coordinates <<1.356, 5.983, 8.458>>.
The expression executes each frame and creates a new particle or sphere at a
random location within a spherical radius of 10 units from the origin.
For example, a scene might have a child of GroupA named Ball.tx and a
different child of GroupB named Ball.tx. If you write this statement:
Ball.tx = time;
Maya generates an error because it doesn’t know which Ball.tx to set.
To eliminate the error, you must enter the pathname of the attribute as in
this example:
GroupA|Ball.tx = time;
The | symbol between GroupA and Ball.tx indicates that the object to the left
of the symbol is the parent of the object to its right. Use no spaces before or
after the | symbol.
Important
Always examine the Script Editor for error messages after you edit an
expression and click the Create button. If you alter a previously successful
Expressions
expression and a syntax error occurs, Maya executes the previous
successful expression when you play the animation. This might lead you to
believe your editing changes took effect.
Example
Ball.tx = $distance;
$distance = time;
Assume for this example you’ve set the starting frame of the animation to
frame 0.
The first statement sets Ball.tx to the variable $distance. The second
statement sets $distance to the value of time.
When you play the animation, Ball moves along the X-axis with the increase
in time. Ball’s X-axis position is 4 grid units, for example, when animation
time equals 4 seconds.
When you rewind the animation, Ball’s position along the X-axis doesn’t
return to 0 as you might assume. The previous execution of the expression at
time equals 4 set the $distance variable to 4. So rewinding sets Ball.tx to 4,
then sets the value of $distance to 0, the value of time upon rewinding.
If you rewind again, Ball’s position along the X-axis returns to 0 as desired.
Because the previous execution of the expression upon rewinding set the
$distance to 0, the expression now correctly sets Ball.tx to 0.
To fix this problem, reverse the order of the statements and compile the
expression:
$distance = time;
Ball.tx = $distance;
After you play and rewind the expression, the first statement executes and
assigns the time to $distance. The next statement assigns Ball.tx the value of
$distance, which the first statement set to the value of time. Because
$distance is set to 0 as the first statement after rewinding, Ball returns to the
desired translateX position.
Increment operations
If you increment an attribute or variable during animation, you might be
confused by its behavior.
Example
Ball.ty = 0;
Ball.ty = Ball.ty + 1;
Ball’s translateY position stays at 1 unit along the Y-axis. Ball’s translateY
position doesn’t increase by 1 each frame as the animation plays.
Example
Ball.ty = Ball.ty + 1;
Ball’s translateY position increases by 1 each frame as you play the
animation. When you rewind the animation, translateY increases by 1 again.
When you play the animation again, the translateY position increases by 1
each frame. If you rewind the animation or drag the current time indicator,
the translateY position continues to move up the Y-axis. The attribute never
returns to its original position.
To return Ball to a starting position each time you rewind, you must
initialize the attribute to a starting value. For example, you could use the
following expression:
Ball.ty = Ball.ty + 1;
if (frame == 1)
Ball.translateY = 0;
This returns Ball to a Y position of 0 when you rewind to frame 1. When you
drag the current time indicator, though, Ball doesn’t return to its Y position
of 0.
The if statement resets the value of translateY to 0 only when frame 1 plays.
Frame 1 is the default frame that plays when you rewind an animation. You
would need to use a different frame number in the if statement if you’ve set
your animation to start at a different frame.
Expressions
type as necessary and doesn’t report a syntax error.
The following topics describe the conversions that occur in such instances.
Understanding these details might help you troubleshoot unexpected
attribute and variable values.
Unless you have programming experience, don’t intentionally convert data
types. You might be confused by unexpected attribute and variable values.
2 2 2
x +y +z
Example
Ball.scaleY = <<1,2,0>>;
Maya assigns the floating point scaleY attribute the converted vector:
2 2 2
1 +2 +0 = 5 = 2.236
Example
Ball.scaleY = 1;
Maya assigns the value 1 to Ball.scaleY.
Example
int $pi = 3.14;
Maya assigns the integer variable $pi the value 3.
int $temp = <<1,2,0>>;
Maya assigns the integer variable $temp this vector value:
2 2 2
1 +2 +0 = 5 = 2.236 ≈ 2
It deletes the decimal component .2360607. The $temp variable receives the
truncated value 2.
Example
vector $speed = 1.34;
Because $speed is a vector, Maya assigns it <<1.34,1.34,1.34>>.
Example
Expressions
Suppose you multiply a vector variable named $velocity by a floating point
number 0.5 as follows:
$race = $velocity * 0.5;
If $velocity is <<2,3,0>> when the preceding expression executes, the $race
variable is assigned the resulting vector value <<1,1.5,0>>.
Important
When Maya does arithmetic operations on literal constants and variables
without a declared data type, it guesses the data type based on the values
present.
In the statement Ball.scaleY = 1/3;, for example, Maya treats 1 and 3 as
integers because they have no decimal points. The expression divides
integer 1 by integer 3. The integer result is 0 with a remainder of 1. Maya
discards the remainder.
Because Ball.scaleY is a floating point attribute, Maya converts the integer 0
result to floating point 0 (which is the same value), then assigns it to
Ball.scaleY.
To get the intended result of 1/3, you must type Ball.scaleY = 1.0/3.0;
Maya treats 1.0 and 3.0 as floating point numbers because they have
decimal points. The number 1.0 divided by 3.0 results in 0.33333333333.
Particle expressions are more complex than other types of expressions. For
example, you can write an expression to control all particles in an object the
same way, or you can control each particle differently.
Execution of expressions differs for particles than for other types of objects.
To become proficient with particle expressions takes more study than for
other expressions, but the resulting effects are worth the effort. This chapter
guides you through the intricacies of working with particle expressions.
Expressions
The particles are displayed as
Spheres render type.
Claude Macri
This chapter has the following topics:
• “Understanding particle expressions” on page 148
• “Understanding creation expression execution” on page 149
• “Writing creation expressions” on page 150
• “Understanding runtime expression execution” on page 152
• “Writing runtime expressions” on page 153
• “Working with particle attributes” on page 159
• “Assigning to vectors and vector arrays” on page 193
• “List of particle shape attributes” on page 196
These buttons let you write two types of expressions: creation and runtime.
You can use both types for any attribute of a particle shape node.
Though the details of execution are subtle, a creation expression generally
executes when you rewind an animation or when a particle is emitted. A
runtime expression typically executes for each frame other than the rewind
frame or the frame in which a particle is emitted. By default, either type of
expression executes once for each particle in the object.
Creation and runtime expressions don’t execute at the same time. The age of
each particle in the object determines whether a runtime expression or
creation expression executes. Execution details are in “Understanding
creation expression execution” on page 149 and “Understanding runtime
expression execution” on page 152.
The Default Object, Always Evaluate, and Convert Units options become
dim when you select a particle shape node, and you can’t use them.
Default Object is dim because a particle shape node’s attributes can be
controlled by only one creation expression and one runtime expression. The
particle shape node is always the default object when it’s the selected object.
Always Evaluate is dim for particle shape node expressions because it has
no effect on particle shape node expressions. See “How often an expression
executes” in Chapter 7 for details on the checkbox.
Convert Units is not selectable because you can’t alter how Maya handles
unit conversions for particle shape node expressions. See “Speeding
expression execution” on page 127 for details on how Maya converts units
for other types of expressions.
Important
You can’t write a different expression for each particle shape attribute as
you can for other types of objects. Because you can write only one creation
expression per particle shape, you don’t need to select an attribute from the
Expression Editor’s Attributes list.
Expressions
You might also notice that all expressions in your scene are compiled and
executed each time you open the scene. This occurs for architectural reasons
and is unimportant to your work with expressions.
Particles created with the Particle Tool have an age of 0 on and before the
Start Frame. With the default animation frame range and Start Frame,
rewinding an animation to frame 1 returns such particles to age 0.
If you set the Time Slider’s start frame higher than the dynamics Start
Frame, be aware that rewinding the animation might cause the age of
particles to be greater than 0. If this occurs, the creation rule for the particles
won’t execute.
Tip
You can set options in the Attribute Editor to display the age of an object’s
particles in the workspace. Set the particle shape’s Render Type to
Numeric, click Add Attributes For Current Render Type, and enter age in
the Attribute Name box. The age appears next to each particle.
You can also examine the age of an object’s particles by entering
print(age+“\n”) in a particle expression. See “print” on page 261.
A creation expression is also useful for initializing an attribute’s value for the
first frame before a runtime expression takes control of the attribute value in
subsequent frames. See “Writing runtime expressions” on page 153 for an
example of the interaction between a runtime and creation expression.
Example
Suppose you’ve used the Particle Tool to place a collection of particles in the
workspace. You then create the following creation expression to control their
velocity:
particleShape1.velocity = <<0,1,0>>;
Expressions
All the particles move in a Y-axis direction at one grid unit per second as the
animation plays.
Important
To use an expression to control particle attributes, make sure the selected
object in the Expression Editor is a particle shape node, not the transform
node of the particle object.
If a particle object’s transform node is selected rather than the particle
shape node, move the mouse pointer to the workspace and press your
keyboard’s down arrow. This selects the particle shape node.
Important
There are no creation expressions for nodes other than particle shape
nodes. Such objects have only one type of expression. (It’s similar to a
runtime expression.)
For a particle shape node, you can write only one runtime expression for
all its attributes. You don’t need to select an attribute from the Attributes
list. You can create only one runtime expression per particle shape.
Example
Suppose you’ve created a grid of particles, then create this runtime
expression for its velocity attribute:
particleShape1.velocity = <<0,1,0>>;
The expression moves the grid of particles up at 1 grid unit per second as the
animation plays.
Expressions
Note
To make the illustrations of particles easier to see in this and other
chapters, we show them as small, shaded spheres rather than points.
With the default frame rate of 24 frames/second, the particles move 1/24 of
a grid unit each frame. With the default oversampling level of 1, the runtime
expression executes once per frame. Maya calculates the runtime expression
once for each particle of an object.
Because the expression sets the velocity to <<0,1,0>> each frame, the
expression executes redundantly. This expression would therefore be more
appropriate for a creation expression. However, either type of expression has
the same effect in this example.
Example
Suppose you’ve created a grid of particles, and your animation’s starting
frame number is 0. You create this runtime expression for its velocity
attribute:
particleShape1.velocity = <<0,time,0>>;
The expression increases the Y component of velocity with the increasing
value of time as the animation plays. This makes all particles in the grid rise
with increasing velocity as the time increases. An increasing velocity is the
same as acceleration.
You need to use the statement in a runtime expression rather than a creation
expression, because you’re increasing a value in the assignment each frame.
Using the statement in a creation expression would instead set the velocity
to a constant value <<0,0,0>>, because time equals 0 when the creation
expression executes for the particle grid.
Example
The previous examples gave all particles the same value for the velocity
attribute. You can instead give each particle a different value for an attribute.
Suppose you’ve created a grid of 121 particles.
Expressions
Suppose further you create this runtime expression for its acceleration
attribute:
particleShape1.acceleration = sphrand(2);
The expression executes once for each of the 121 particles each time the
runtime expression executes.
The sphrand(2) function provides a vector whose randomly selected
components reside within an imaginary sphere centered at the origin and
with a radius of 2. Each particle receives a different vector value. For details
on the sphrand function, see “sphrand” in Chapter 9.
Because each particle receives a different random vector for its acceleration
each frame, the particles accelerate individually in a constantly changing
direction and rate as the scene plays. This gives the acceleration abrupt
changes in direction.
Important
To give particles a constant acceleration, assign the acceleration attribute a
constant value in a runtime expression rather than in a creation expression.
Maya simulates the physics of acceleration. It initializes acceleration to
<<0,0,0>> before each frame, or if the oversample level is greater than 1,
before each timestep.
If the oversample level is 2, there are 2 timesteps per frame. If the
oversample level is 3, there are 3 timesteps per frame, and so on.
Example
Suppose you’ve set your animation’s starting frame to 0, and you’ve used
the Particle Tool to place a single particle at the origin:
Expressions
Each subsequent frame moves the particle upward at a rate set by the
incrementing value of time.
When you stop and rewind the animation, the particle moves back to the
origin, the particle’s original position when you created it with the Particle
Tool. When you created the particle, Maya stored its original position in an
internally maintained initial state attribute named position0. For details, see
“Understanding initial state attributes” on page 162.
Because the attribute has no creation expression controlling its value, Maya
sets the attribute to its initial state position0 value of <<0,0,0>>.
To prevent the particle from jumping back to the origin after rewinding, you
can write a creation expression that’s the same as the runtime expression:
particleShape1.position = <<3,time,0>>;
When you rewind the animation, the particle moves to position
<<3,time,0>>. Because time is 0 at frame 0, the particle starts at position
<<3,0,0>> when you rewind the animation. In the second and following
frames, it moves upward synchronized with the increasing value of time.
Though this example showed how to initialize the position attribute with a
creation expression, you could have gotten almost the same result by saving
the object’s current attribute values for initial state usage:
When you rewind the animation, Maya positions the object at the initial state
setting of its position attribute. This setting is <<3, 0.0417, 0>> because you
selected Set for Current while the position was equal to <<3, 0.0417, 0>>.
Expressions
You also use expressions to control dynamic and custom attributes you add
to a particle shape node. See “Attributes” in Chapter 5 for details on the
differences between static, dynamic, and custom attributes. See “Assigning
to a custom attribute” on page 169 for details on working with custom
attributes.
When you add a dynamic attribute to an object, the attribute names appear
in the Expression Editor’s Attributes list.
Note
See “List of particle shape attributes” on page 196 for attributes you can
use with particle objects.
The most common way to create dynamic per object or per particle attributes
for a particle shape is by clicking one of the following buttons in the Add
Dynamic Attributes section of the Attribute Editor:
For example, if you click the Opacity button, a window appears and lets you
choose whether to add the opacity characteristic as a per object attribute or a
per particle attribute.
If you choose per particle, the Attributes list of the Expression Editor
displays a new attribute for the selected particle shape node: opacityPP. If
you choose per object, an opacity attribute is displayed instead.
For attributes other than lifespan, if you add both a per particle attribute and
a per object attribute for a characteristic, the per particle attribute takes
precedence. For instance, if you add opacity and opacityPP, the opacityPP
attribute controls the opacity of the particles of the specified object.
When you click Lifespan and add both a per particle and per object
attribute, Maya adds an additional attribute named useLifspanPP that lets
you choose whether lifespanPP or lifespan controls the characteristic.
By default, the Attribute Editor setting of useLifespanPP is on, so the
Expressions
lifespanPP attribute control the characteristic. If you turn useLifespanPP off
in the Attribute Editor, lifespan controls the characteristic.
If you click the Goal button in the Add Dynamic Attributes section of the
Attribute Editor, Maya adds a per object attribute and a per particle
attribute. The attributes are named goal and goalPP. Neither attribute has
precedence. Maya multiplies the value of the per object goal attribute by the
per particle goalPP attribute to create the final goal effect for each particle.
Important
You can use per particle attributes only in particle expressions. You can use
per object attributes in particle or nonparticle expressions.
If you use a runtime expression to read or write a per object attribute of a
particle object with many particles, you can speed up expression execution
by reading or writing the attribute in a nonparticle expression.
Nonparticle expressions execute only once per object. Particle expressions
execute once for each particle in the object. Because reading or writing a
per object attribute more than once per frame is redundant, you can save
processing time by working with them in nonparticle expressions.
When you use the Add Attribute window to add a custom per particle
(array) attribute to a particle shape, you must choose whether you want to
add it with Add Initial State Attribute on or off. If you choose on, Maya
creates a corresponding initial state attribute for the added attribute.
If you choose off, Maya doesn’t create a corresponding initial state attribute
for the added attribute. Without this corresponding attribute, you can’t save
a particle object’s current attribute values for initial state usage. You must
write a creation expression if you decide to initialize the custom attribute’s
value upon rewinding the animation.
Note
A per particle attribute is called an array attribute in the Add Attribute
window. The two terms have the same meaning. See “Assigning to a
custom attribute” on page 169 for details.
You can see whether a custom attribute was added with Add Initial State
Attribute on or off by using the MEL listAttributes command. (See the online
MEL documentation for details.)
You might want to read the value of an initial state attribute in an
expression, for instance, to use its original (rewind) value for some
calculation. If you assign a value to an initial state attribute. Maya will
overwrite the value if you save the attribute value for initial state usage.
Expressions
When you add a custom attribute to a particle shape, do not end the name
with a 0 character. You’ll subvert Maya’s naming scheme for the initial state
attribute associated with an attribute.
For any attribute, if you don’t initialize its value with a creation expression
or save its value for initial state usage, Maya gives the attribute a default
value at the animation’s first frame. It typically assigns the attribute the
value 0 or <<0,0,0>>, as appropriate for the data type. In other cases, for
instance, opacityPP and opacity, Maya assigns the attribute a default value
of 1.
If you know you’re going to write a creation expression for a custom
attribute, you can set Add Initial State Attribute off when you add the
attribute. Otherwise, set Add Initial State Attribute on whenever you add a
custom attribute.
When a creation expression assigns a value to an attribute, the value
overrides the attribute’s initial state value for all particles whose age is 0.
The following steps show how to assign a different lifespanPP value for each
of the particles to make them disappear as the scene plays.
Because lifespanPP is a per particle attribute and the object’s particle shape
node is selected in the Expression Editor, the expression does an execution
loop of both statements once for each particle in the object.
Because the expression is a creation expression, it executes after the
expression compiles. It also executes when you rewind the animation after
playing it.
For each of the particles, the first statement assigns the lifespanPP attribute a
random floating point number between 0 and 5. The rand function returns a
different random number each time it executes, so each particle has a
different lifespanPP value between 0 and 5. For details on the rand function,
see chapter 9, “Functions.”
The second statement displays Hello in the Script Editor, once for each
particle.
The creation expression gives each particle a random lifespanPP of less than
5 seconds. The particles disappear from the scene at random times between 0
and 5 seconds of scene play. (Maya gives particles created with the Particle
tool an age of 0 in the first frame of the animation.)
Expressions
Particles remaining after
three seconds, with creation
expression for lifespanPP.
When you rewind the animation, the particles reappear in the scene. Playing
the scene again makes them disappear at random times within 5 seconds.
It’s important that you use a creation expression for this effect. If you were
to use a runtime expression, the particles would disappear more quickly as
the animation plays, and Hello would appear 100 times each frame. The
reason for this is subtle:
In each frame, a runtime expression would assign a different random value
between 0 and 5 seconds to the lifespanPP of each particle. The expression
would likely assign one or more of the particles a lifespanPP near 0.
Meanwhile, the age of each particle increases from 0 at the first frame of
play.
Maya checks the age of each particle every frame. If the age is greater than
the lifespanPP value, Maya removes the particle.
Because the expression would reassign new random lifespanPP values to
each remaining particle in each frame, the new assignments would likely
give a few particles a lifespanPP that’s less than their current age value.
Maya deletes such particles. This causes the object’s particles to disappear
quickly from the scene.
The following steps show how to give the particles a single lifespan. All
particles disappear at the same time when you play the scene.
Expressions
2 In the Add Dynamic Attributes section of the Attribute Editor, click the
Lifespan button.
A window appears that prompts you to choose whether to add the attribute
per object or per particle.
3 Select Add Per Object Attribute, then click the Add Attribute button.
This adds the lifespan attribute to the particle shape node for Bubbles.
4 In the Expression Editor, turn on Creation.
5 Create this creation expression:
BubblesShape1.lifespan = 1.33;
print("Hello\n");
Because this is a creation expression, it executes after the expression
compiles. It also executes when you rewind the animation after playing it.
For each of the 100 particles, the first statement assigns the lifespan attribute
the value 1.33. The second statement displays Hello in the Script Editor once
for each particle.
6 Play the animation.
Because all particles have a lifespan of 1.33, they disappear from the scene
after 1.33 seconds of animation play.
When you rewind the animation, the particles reappear in the scene. Playing
the scene again makes them disappear again after 1.33 seconds.
Expressions
The new attribute appears under the Dynamic Attributes section of the
Attribute Editor.
Example
Suppose you’ve created a 100-particle object named sunspot, and you add to
its particle shape node a vector per object attribute named glow. You assign
the glow attribute a vector value in a creation expression as follows:
sunspotShape1.glow = <<3,0,0>>;
print(sunspotShape1.glow + "\n");
When you rewind the animation, the glow attribute of sunspotShape1
receives the value <<3,0,0>>. The print statement displays the values in the
Script Editor.
Example
Suppose you add a vector per particle attribute named heat to the 100-
particle sunspot shape node. You can give each particle a different value as
in this creation expression:
Expressions
float $randomNumber = rand(1);
sunspotShape1.heat = <<$randomNumber,0,0>>;
print(sunspotShape1.heat + "\n");
When you rewind the animation, the expression loops through 100
executions, once for each particle.
The first statement sets the $randomNumber variable to a random number
between 0 and 1. The next statement assigns a vector to the heat attribute of
a single particle. The left component of the vector assigned to heat is a
different random number each time the statement executes. The middle and
right components are always 0.
One particle might have the value <<0.57, 0, 0>>, another <<0.32, 0, 0>>,
another <<0.98, 0, 0>>, and so on.
The print statement displays the values in the Script Editor.
Note
If you add a custom vector attribute to an object, Maya displays the
attribute in the Attribute Editor, but you can’t enter its value there. You
must enter a value for it in an expression or with the Component Editor
available from the Attribute Editor.
Example
Suppose your scene contains an object named ThreePts made of three
particles and an object named TwoPts made of two particles.
The three particles in ThreePts are at these positions:
-5 0 0
-4 0 0
-3 0 0
The two particles in TwoPts are at these positions:
5 0 0
6 0 0
Expressions
Suppose you write the preceding runtime expression instead with
ThreePtsShape1 selected in the Object Selection list.
Again, the expression repositions the three particles to the position of the
two particles. Because you selected ThreePtsShape1 in the Object Selection
list, the expression executes once for each of its three particles.
When you play the scene, the runtime expression executes. The first particle
of ThreePts moves to the position of the first particle of TwoPts. The second
particle of ThreePts moves to the position of the second particle of TwoPts.
Expressions
Unless you have a solid grasp of physics, avoid setting a combination of the
position, velocity, and acceleration attributes.
To give a smooth, random motion to particles with a runtime expression, use
a random number function such as sphrand to assign random numbers to
the particle shape’s acceleration attribute. A change in acceleration always
gives smooth motion no matter how abruptly its value changes.
To give a jittery random motion to particles with a runtime expression, use a
random number function such as sphrand to assign random numbers to the
particle shape’s velocity or position attributes.
See “Random number functions” on page 239 for details on how to use
random number functions.
If an expression and a dynamic field control an object’s position, velocity, or
acceleration, Maya calculates the expression’s effect first, then adds the
field’s effect.
Example
Suppose a particle drops under the influence of a gravity field with default
gravity options. Gravity accelerates the particle at 9.8 units per second per
second down the Y-axis. In other words, the default acceleration of gravity is
<<0,-9.8,0>>.
Suppose further you write the following runtime expression for the particle:
velocity = velocity + <<1,0,0>>;
As each frame plays, Maya first calculates the particle’s velocity from the
expression statement. The velocity increases 1 unit per second in an X-axis
direction. Maya then adds the gravitational acceleration to the velocity.
Maya uses the combined result to compute the particle’s position.
Of course, you won’t see this calculation process. The frame displays the
particle in the appropriate position after all computation.
Note that the expression adds the constant <<1,0,0>> to the particle’s
velocity each frame as the animation plays. This makes the particle move
with increasing velocity in an X direction as the time increases. An
increasing velocity is the same as acceleration.
Example
Suppose you write the following runtime expression for a five-particle object
unaffected by gravity:
acceleration = acceleration + <<0,1,0>>;
Rather than adding <<0,1,0>> to the acceleration value each frame,
acceleration remains a constant <<0,1,0>> for each of the particles. This
happens because Maya initializes the value of acceleration to <<0,0,0>>
before each frame.
Suppose you connect the particle object to gravity with default settings. The
acceleration of the particle becomes <<0,1,0>> plus <<0,-9.8,0>>, which
equals <<0,-8.8,0>>. The acceleration assigned in the expression slows the
downward acceleration of the gravity.
Suppose you change the previous expression to this:
acceleration = acceleration + sphrand(3);
Because Maya sets acceleration to <<0,0,0>> before each frame, the
Expressions
statement has the same result as the following statement:
acceleration = sphrand(3);
As each frame plays, Maya first calculates each particle’s acceleration from
the expression statement. Each particle receives the result of the sphrand(3)
function.
The sphrand(3) function provides a vector whose randomly selected
components reside within a spherical region centered at the origin with
radius 3. Each particle receives a different vector value.
Finally, Maya adds gravity’s acceleration to the expression acceleration
resulting from sphrand(3). The frame displays each particle in the resulting
position.
Because of the random values resulting from the expression, each particle
has an acceleration that differs slightly from gravity in direction and
magnitude. Because the sphrand(3) function executes for each particle each
frame, the acceleration of each particle varies each frame.
This example shows that you can take advantage of the additive effect of
fields and the acceleration attribute to create custom field effects.
Tip
You can turn off the effect of all fields on a particle shape node attribute by
setting its dynamicsWeight attribute to 0.
Example
Suppose you’ve used the Particle tool to create a randomly positioned
collection of particles named Bubbles. You can use a creation expression to
give the particles a constant color during animation play.
Expressions
3 Select Add Per Particle Attribute, then click the Add Attribute button.
This adds an rgbPP attribute to the particle shape node for Bubbles. Because
you’re adding this attribute as a per particle attribute, you can give each
particle a different color.
4 Choose Shading→Smooth Shade All.
This step is necessary to make the correct particle color appear when you
assign the rgbPP attribute a value in an expression.
5 In the Expression Editor, select Bubble’s particle shape node.
6 Turn on Creation in the Expression Editor.
Because you’ll give the particles a color that doesn’t change during the
animation, you use a creation expression.
7 Enter this expression:
BubblesShape1.rgbPP = <<1,0,0>>;
When you click the Create button in the Expression Editor, Maya checks the
syntax of the expression. Assuming you made no typing errors, the
expression executes once for each of the 100 particles.
The expression colors all particles in the object red. The double angle
brackets << and >> enclose a vector that sets the red, green, and blue
components of the rgbPP attribute to 1, 0, and 0. In the RGB color scheme,
this gives the object a red color.
8 Play the animation.
Because the expression is a creation expression, it executes when you rewind
the animation. The particles remain red for entire animation because the red
color is never changed by a runtime expression.
Tip
See the online version of this documentation for colored illustrations.
The following steps show how to give the particles a randomly changing
color as the animation plays.
Because the creation expression executes when you rewind, the particles are
red.
5 Play the animation.
The runtime expression takes control of the rgbPP attribute. Because rgbPP
is a per particle attribute, the runtime expression executes for each particle in
the object each frame. For each particle, the expression assigns the rgbPP
attribute the output from the execution of the sphrand function with an
argument of 1.
The sphrand function assigns each particle’s rgbPP color a random vector.
The vector represents a random point in a spherical region of radius 1. The
left, middle, and right rgbPP color components have a value no less than -1
and no greater than 1. Values less than 0 are treated as 0.
The sphrand function returns a different random vector each execution. So
each particle has a different random rgbPP value, and therefore, a different
color. The color of each particle changes each frame.
Expressions
If you rendered the animation and played it back at 24 frames per second,
you would have trouble seeing the color of a particle in any instant because
the color changes so quickly.
You can slow the change of colors to create a flashing Christmas light effect.
The following steps make the particles change colors every second of
animation.
This expression uses the modulus operator (%) to control when the rgbPP
attribute of the particles receives a random color. The modulus operator
returns the remainder after division. For example, 24 divided by 24 returns
0, but 25 divided by 24 returns 1. (Dividing 25 by 24 equals 1 with a
remainder of 1.)
If the value of frame divided by 24 is equal to any number with a remainder
of 0, the assignment to BubblesShape1.rgbPP occurs. In other words, the
assignment occurs when frame equals 24, 48, 72, and so on. At an animation
rate of 24 frames/second, the assignment happens once each second.
Important
Avoid using the modulus operator with floating point values. Because of
number rounding in floating point division, you won’t likely get a return
value of exactly 0 with the modulus operator. Instead use an integer value
when possible.
Note that you can change the red rewind color to random colors by
changing the creation expression to this:
BubblesShape1.rgbPP = sphrand(1);
This is the same expression as the runtime expression.
Example
Suppose you’ve created an emitter and added a per particle lifespanPP
attribute to it. The following creation expression gives the emitted particles a
lifespan of 2 seconds:
particleShape1.lifespanPP = 2;
Each particle disappears two seconds after it’s emitted.
Important
Avoid assigning a per particle attribute to another object’s per particle
Expressions
attribute if the particles of either object die. As particles die, the order of
expression evaluation changes for the object’s particles. This causes
unexpected results.
You can, though, assign from one attribute to another in the same object
with dying particles. The array indexes of the different attributes are in
synch with each other.
For example, don’t write an expression like this:
emittedShape1.lifespanPP = 2;
emittedShape1.rgbPP = otherParticleShape2.rgbPP
The eventCount and eventTest are static attributes. A particle shape node
has them as soon as you create the particle object. Though they don’t appear
in the Expression Editor, you can use their values in an expression. You
must first create the event attribute as described previously.
Example
Suppose you’ve created a five-particle object named Peas that falls with
gravity and collides with a plane.
You can make the particles turn red when the first particle hits the plane.
1 Select PeasShape1 in the Outliner or Hypergraph.
2 From the Dynamics menu bar, select Settings→Particle Collision Events.
Expressions
3 In the Particle Events window, click Create Event, then close the window.
This adds an event attribute to PeasShape1.
4 In the Add Dynamic Attributes section of the Attribute Editor, click Color.
The Particle Color window appears.
5 Select Add Per Particle Attribute, then click Add Attribute.
This adds a per particle attribute named rgbPP. This attribute controls the
red, green, and blue color scheme of each particle.
The particles turn black after you add the rgbPP attribute. Adding the rgbPP
attribute turns off the default coloring of the particles and gives them a value
of <<0,0,0>>.
6 Choose Shading→Smooth Shade All.
This step is necessary to make the correct particle color appear when you
assign the rgbPP attribute a value in an expression.
else if (event == 2)
rgbPP = <<0,1,0>>;
Tip
See the online version of this documentation for colored illustrations.
Note that the value of the event attribute reflects the collision count in the
frame after each collision. For example, if a particle collides with the plane in
frame 10, event is updated in frame 11.
When the other particles hit the plane for the first time, they also turn red
Expressions
after they collide.
A particle stays red until it collides with the plane for the second time, when
event equals 2. After a second collision, the particle turns green.
Note that Set for Current saves all attribute values, including position,
velocity, acceleration, and so on. In cases where you have several changing
attribute values during playback, Set for Current might save undesired
attribute values in addition to the desired ones. In such cases, use a creation
expression.
Expressions
2, and so on.
You can assign per particle attribute values to specific particles using the
particleId attribute.
Example
Suppose you’ve used the Particle tool to create a grid of eight particles
named ColorGrid. In the Attribute Editor, you’ve set the Render Type of the
particles to Spheres. You’ve chosen Shading→Smooth Shade All to display
the particles with shading.
You can give the particles different colors based on their particleId.
Expressions
The expression’s first statement assigns a red color to all particles whose
particleId is less than or equal to 2. The value <<1,0,0>> is red in the RGB
color scheme.
The second statement assigns a white color to all particles whose particleId
is greater than 2 and less than 6. The value <<1,1,1>> is white in the RGB
color scheme.
The third statement assigns a blue color to all particles that don’t meet the
conditions in the prior two statements. In other words, all particles whose
particleId is greater than or equal to 6 become blue. The value <<0,0,1>> is
blue in the RGB color scheme.
The following steps show another common way to control an attribute based
on the particleId attribute.
To color half the particles red, and half the particles blue:
1 Enter the following runtime expression:
if ((particleId % 2) == 0)
rgbPP = <<1,0,0>>;
else rgbPP = <<0,0,1>>;
2 Play the scene.
The runtime expression executes each frame as the animation plays. Half the
particles are blue, half are red.
The first statement uses a modulus operator (%) to calculate the remainder
of dividing a particleId by 2. It then compares the remainder to 0. If the
remainder equals 0, the statement assigns the particle a red color. The value
<<1,0,0>> is red.
The second statement assigns a particle a blue color if the remainder of the
modulus operation doesn’t equal 0. The value <<0,0,1>> is blue. For
example, dividing particleId 0 by 2 equals 0 with remainder 0. Because the
remainder is 0, the particle having particleId 0 receives a red color.
Dividing particleId 1 by 2 equals 0 with remainder 1. Because the remainder
is 1, the particle having particleId 1 receives a blue color.
Dividing particleId 2 by 2 equals 1 with remainder 0. With remainder 0, the
particle having particleId 1 receives a blue color. The expression executes for
each particle in the object.
The result is that even-numbered particleIds become red, odd numbered
particles become blue.
3 Rewind the animation.
The creation expression executes. The particles become red, white, and blue
as described for the previous expression.
4 Play the animation.
The runtime expression executes each frame. The particles are red and blue
as the animation plays.
Note to programmers
You cannot assign values to individual particles with the array index
notation commonly used in programming languages.
For example, suppose you’ve created an opacityPP attribute for an object
made of three particles. You can’t assign values as in this example:
opacityPP[0] = 0.3;
opacityPP[1] = 0.5;
opacityPP[2] = 1;
Expressions
Assigning to a vector variable
You can assign a literal vector value or another vector variable to a vector
variable. Enclose a literal vector value in double angle brackets.
Examples
vector $top_velocity = <<2,2,5>>;
This assigns the vector $top_velocity the value <<2,2,5>>.
vector $temp;
vector $temp = $top_velocity;
This assigns the value of vector variable $top_velocity to the vector variable
$temp.
Format Meaning
Examples
float $temp;
vector $myvector = <<1,2,3>>;
float $temp = $myvector.z;
This assigns the right component of $myvector, 3, to the floating point
variable $temp.
Suppose you have a vector initialized as follows:
vector $myvector = <<1,2,3>>;
To replace the right component of $myvector, 3, with a new value such as 7,
use this technique to preserve the other two components:
$myvector = <<$myvector.x,$myvector.y,7>>;
This statement is incorrect:
$myvector.z = 3;
An error occurs. A statement can read, but not directly assign, a component
of a vector variable.
Example
Suppose you have 100-particle Cloud of randomly positioned particles.
CloudShape1.position = sphrand(1);
vector $pos = CloudShape1.position;
CloudShape1.rgbPP = <<0,$pos.y,0>>;
The three statements execute once for each particle in Cloud.
The first statement gives a particle a random position within a spherical
region of radius 1. The sphrand(1) function gives the X, Y, and Z position
components a value no less than -1 and no greater than 1.
The second statement assigns a particle’s position to a vector variable $pos.
The third statement assigns an RGB color to a particle’s rgbPP attribute.
The left, middle, and right vector components of CloudShape1.rgbPP
represent red, green, and blue components of the RGB color scheme. The
third statement therefore assigns 0 (no color) to the red and blue components
of a particle’s colorRGB. It gives a particle’s green component the value of its
Y coordinate position.
Because a value of 0 or less results in a 0 green value, a particle is black if it’s
below the XZ plane. If a particle’s Y coordinate position is above the XZ
plane, it has a green component varying from nearly 0 to a fully saturated
green.
Expressions
This colors the particles from black to green, depending on the position.
Increasingly green
Example
particleShape1.rgbPP = <<1,0,CloudShape1.position.z>>;
This causes an error. Maya interprets CloudShape1.position.z as being an
attribute named z of an object named CloudShape1.position.
You can get the intended result with these statements:
vector $temp = CloudShape1.position;
particleShape1.rgbPP = <<1,0,$temp.z>>;
The first statement reads all three components of vector attribute
CloudShape1.position and assigns it to the vector variable $temp. The
second statement reads the value of the right component of $temp, which
contains the right component of CloudShape1.position. It then assigns this
component to the right component of particleShape1.rgbPP.
Example
particleShape1.rgbPP.y = 1;
This also causes an error. You can’t assign a value to a vector array attribute
component.
Expressions
colorGreen Sets green component of MultiStreak float
RGB color. Points
colorRed Sets red component of Sphere float
RGB color. Sprite
Streak
conserve Sets amount of float
(con) momentum conservation.
Expressions
applies to each particle in
the object.
radiusPP Sets radius size on a per yes Blobby Surface float array
particle basis. Cloud
Sphere
Expressions
selectedOnly Toggles display of id Numeric boolean
numbers for selected
particles.
Matt Baer
Expressions
For easy reference, this chapter groups functions by their purpose. For
example, all math functions are grouped in the same section.
Expressions
Other functions and 264
commands
Understanding functions
A function generates a value where it occurs in an expression statement. It
takes action based on parameters called arguments that you enclose in
parentheses next to the function name.
Example
Suppose you have an object named Star whose translateX attribute is set
with this expression statement:
Star.translateX = rand(10);
In this statement, the rand function has the argument 10. With this
argument, the function generates a randomly selected floating point number
between 0 and 10 each time the statement executes. For example, translateX
might be assigned 6.5409 the first time the statement executes, 3.2974 the
second time, 8.7389 the third time, and so on. This causes Star to jump to
random points from 0 to 10 units away from the X-axis as the scene plays.
Though functions can be more or less complicated than this example, they
all have at least one argument and generate one value. Note that a function
is part of an expression statement. They don’t stand alone in an expression.
Many functions do mathematical operations. For example, the sin function
generates the sine of a specified angle. Though we often provide explanatory
figures and details, we assume you’re familiar with the mathematical
purpose of such functions. For details on the math behind such functions,
see a more elementary reference.
Note that the following functions are important to learn if you want to go
beyond the basics of expression writing:
• sin or sind
• linstep
• smoothstep
• hermite
• noise
• dnoise
• rand
• sphrand
• print
Function syntax
To help you quickly reference different functions, this chapter includes a
syntax format statement for each function. The format follows:
datatype function(datatype argument)
function is the name of the function.
datatype to the left of an argument indicates the data type of the argument.
argument is a parameter you type with the function.
datatype to the left of the function name indicates the data type returned
when the function executes.
Note that for either datatype, you don’t type a value. The datatype tells you
the type of data you must enter or the data type returned by the executed
function.
The data types are in small type size for easy identification in the syntax
definitions.
Example 1
int abs(int number)
float abs(float number)
vector abs(vector number)
The function name is abs, which returns the absolute value of the number of
your choice. The absolute value of a number is the number without its
positive or negative sign.
This example shows the abs function has three formats. Each version
requires an argument with a different data type and returns a value with a
different data type.
The first version indicates that you can type an integer argument, and the
function returns an integer result. For example, abs(-3) returns 3.
The second version indicates that you can type a floating point argument,
and the function returns a floating point result. For instance, abs(-7.54)
Expressions
returns 7.54.
The third version indicates you can type a vector, and the function returns a
vector. For example abs(<<3, -6.3, -2>>) returns <<3, 6.3, 2>>.
Example 2
Many functions have only one format, for example, the deg_to_rad function:
float deg_to_rad( float degrees )
This function returns the radian equivalent of to a degree value. It expects a
floating point argument and returns a floating point number.
Note that Maya ignores spaces between components of functions. For
example, the functions in each of these expressions work the same:
rotateY = deg_to_rad (45);
rotateY = deg_to_rad(45);
rotateY = deg_to_rad( 45 );
Data types
In many cases, entering a data type other than the type expected by a
function causes an error and prevents the expression from executing. For
example, if you enter a vector argument where a floating point number is
expected, an error occurs.
For a function argument that expects a floating point number, however, you
can instead type an integer—a number without a decimal point. Maya
converts an integer to a floating point number in arithmetic operations.
If an error occurs when you create an expression, check that you’re using the
appropriate data types for all arguments.
Notes
In this book, examples of floating point return values show no more than
three digits to the right of the decimal point. If you display the contents of
an attribute or variable in the Script Editor, you’ll see as many as 10 digits
to the right of the decimal point.
For instance, an example might show a return value as 3.539 rather than
the precise value 3.538654390. The examples round up such numbers for
ease of reading.
Note also that converting radians to degrees and vice versa results in
rounding errors. For example, converting a radian value might result in
89.99999996 degrees rather than 90.0 degrees.
Examples
Ball.scaleY = abs(-1);
This statement assigns Ball.scaleY the value returned by the abs(-1) function.
If you use a function in an expression statement and do not assign the
returned value to an attribute, the statement has no effect.
abs(-1);
Returns 1, but doesn’t assign it to an attribute. This has the same result as
the following meaningless statement:
1;
In some function examples in this chapter, the function’s purpose is easier to
understand in the context of an expression. In such cases, we show examples
of the function in an expression.
Limit functions
The limit functions are math functions that impose limits on numbers.
abs
Returns the absolute value of number. The absolute value of an integer or
Expressions
floating point number is the number without its positive or negative sign.
The absolute value of a vector is a vector with components stripped of
negative signs.
int abs(int number)
float abs(float number)
vector abs(vector number)
number is the number for which you want the absolute value.
Examples
abs(-1)
Returns the value 1.
abs(1)
Returns the value 1.
abs(<<-1,-2.43,555>>)
Returns <<1, 2.43, 555>>.
abs(Ball.translateY)
If Ball.translateY contains -20, this returns 20.
ceil
Returns a number rounded to the smallest integer value greater than or
equal to a floating point number.
float ceil(float number)
number is the number you want to round.
Examples
ceil(2.344)
Returns 3.
ceil(3.0)
Returns 3.
ceil(Rock.scaleY)
If Rock.scaleY contains -2.82, this returns -2.
floor
Returns a number rounded to the largest integer less than or equal to a
floating point number.
float floor(float number)
number is the number you want to round.
Examples
floor(2.344)
Returns 2.
floor(3.0)
Returns 3.
floor(Head.height)
If Head.height is -2.8, this returns -3.
clamp
Returns a number within a range. You can use the clamp function to confine
an increasing, decreasing, or randomly changing number to a range of
values.
float clamp(float minnumber, float maxnumber, float parameter)
minnumber and maxnumber specify the range of the returned value.
parameter is an attribute or variable whose value you want to clamp within
the range.
If parameter is within the numerical range of minnumber and maxnumber, the
function returns the value of parameter.
If parameter is greater than the range, the function returns the maxnumber.
If parameter is less than the range, the function returns the minnumber.
Examples
clamp(4,6,22)
Expressions
Returns 6, because 22 is greater than 6, the maximum number of the range.
clamp(4,6,2)
Returns 4, because 2 is less than 4, the minimum number of the range.
clamp(4,6,5)
Returns 5, because it’s within the range.
Ball.scaleY = clamp(0,3,time);
Returns a value between 0 and 3 each time the expression executes.
When you rewind the animation to frame 1, the above expression executes
and Ball’s scaleY attribute receives the value of time—a number slightly
above 0. The clamp function returns the value of time because time is within
the range 0 to 3.
When you play the animation, time increments slightly with each frame. The
expression executes with each frame and Ball’s scaleY attribute receives the
value of time until time exceeds 3. When time exceeds 3, the clamp function
returns the value 3.
min
Returns the lesser of two floating point numbers.
float min( float number, float number)
number is a number you want to compare.
Examples
min(7.2,-3.2)
Returns -3.2.
Desk.height = -2;
Lamp.height = 9;
$Mylight = min(Desk.height,Lamp.height);
Sets $Mylight to -2.
max
Returns the larger of two floating point numbers.
float max(float number, float number)
number is a number you want to compare.
Examples
max(7.2,-3.2)
Returns 7.2.
Desk.height = -2;
Lamp.height = 9;
$Mylight = max(Desk.height,Lamp.height);
Sets $Mylight to 9.
sign
Returns one of three values representing the sign of a number. Returns -1 if
the number is negative, 1 if positive, 0 if 0.
float sign( float number )
number is the number whose sign you want to determine.
Examples
sign(-9.63)
Returns -1.
sign(0)
Returns 0.
sign(10)
Returns 1.
sign(Ball.translateX)
If Ball.translateX is 5, this returns 1.
trunc
Returns the whole number part of a floating point number.
float trunc(float number)
number is the number you want to truncate.
Examples
trunc(2.344)
Expressions
Returns 2.
trunc(0.3)
Returns 0.
trunc(-2.82)
Returns -2.
trunc(time)
If time equals 3.1234, this returns 3.
Exponential functions
The following functions work with exponential values.
exp
Returns e raised to the power of a number, enumber. The predefined variable e
is the base of the natural logarithm, which is 2.718.
float exp(float number)
number is the exponent to which you want to raise e.
Examples
exp(1)
Returns 2.718, the value of e.
exp(2)
Returns 7.389, the value of e2.
log
Returns the natural logarithm of a number, logenumber. The natural
logarithm uses the constant e, which is 2.718.
float log(float number)
number is the positive number for which you want the natural logarithm.
Examples
log(10)
Returns 2.303.
log(2.718282845904)
Returns 1.000.
log10
Returns the log base 10 of a number.
float log10(float number)
number is the positive number for which you want the log base 10.
Examples
log10(100)
Returns 2.
log10(10)
Returns 1.
pow
Returns a base number raised to an exponent.
float pow(float base, float exponent )
base is the base number you want to raise to the exponent. A negative base
number with a decimal component causes an error message.
exponent is the exponent.
Examples
pow(2,3)
Returns 8.
pow(-2,3)
Expressions
Returns -8.
pow(2,-3)
Returns 0.125.
sqrt
Returns the square root of a positive number.
float sqrt(float number)
number is the positive number of which you want the square root.
A negative number displays an error message.
Examples
sqrt(16)
Returns 4.
sqrt($side)
If $side is 25, this returns 5.
Trigonometric functions
The following functions return trigonometric values. Each function has two
formats that let you choose the type of angular unit you work with: degrees
or radians. For example, the cos function expects an argument in radians,
while cosd expects an argument in degrees.
A radian equals 180 degrees divided by pi, or roughly 57.3 degrees. Note
that pi equals 3.1415927, which is also 180 degrees.
cos
Returns the cosine of an angle specified in radians.
float cos(float number)
number is the angle, in radians, whose cosine you want.
For any right triangle, the cosine of an angle is the following ratio:
adjacent B
cos θ = ------------------------------ = ----
hypotenuse C
Y Y
C
A θ
θ B
B X X
A
C
The cosine ratio depends only on the size of the angle and not on the size of
the triangle. This constant ratio is called the cosine of the measure of the
angle.
The cosine ratio is a value between -1 and 1.
With a steadily increasing or decreasing argument, the cos function returns
steadily increasing or decreasing values between 1 and -1. This is useful for
creating rhythmic, oscillating changes in attribute values.
The cos function works like the sin function except its return values are 90
degrees, or pi/2, out of phase.
See page 219 for ideas on how to use the cyclical characteristics of the sin
and cos functions.
Example 1
cos(1)
Returns 0.5403, the cosine of 1 radian.
Example 2
To animate the motion of Ball in a cosine wave pattern, use this expression:
Ball.translateX = time;
Ball.translateY = cos(Ball.translateX);
Expressions
Ball starts at the origin and moves in the X direction at a rate set by the
incrementing animation time. Its Y translation moves cyclically up and
down according to the return values of the cos function. The cos function
uses translateX, and therefore indirectly, time, as its argument.
As time increases from 0 to 6.283 seconds, the cos function returns values
that change in fine increments from 1 to -1 and back to 1. The value 6.283 is 2
times the value of pi.
As time increases beyond 6.283 seconds, the same cycle repeats for each span
of 6.283 seconds.
Ball.translateY = cos(Ball.translateX);
time = 6.283
(2 * pi seconds)
Ball.translateY = sin(Ball.translateX);
time = 6.283
(2 * pi seconds)
The cosine curve is 1.571 (pi/2) seconds ahead of (or behind) the sine curve,
and vice versa.
cosd
Returns the cosine of an angle specified in degrees.
float cosd(float number)
number is the angle, in degrees, whose cosine you want.
For more details on the cosd function, see the cos function in the preceding
topic. The cosd and cos functions do the same operation, but cosd requires
its argument in degree measurement units.
Example
cosd(45)
Returns 0.707, the cosine of 45 degrees.
sin
Returns the sine of an angle specified in radians.
float sin(float number)
number is the angle, in radians, whose sine you want.
For any right triangle, the sine of an angle is the following ratio:
opposite A
sin θ = ------------------------------ = ----
hypotenuse C
Y Y
C
A θ
θ B
B X X
Expressions
A
C
The sine ratio depends only on the size of the angle and not on the size of
the triangle. This constant ratio is called the sine of the measure of the angle.
The sine ratio is a value between -1 and 1.
With a steadily increasing or decreasing argument, the sin function returns
steadily increasing or decreasing values between -1 and 1. This is useful for
creating rhythmic, oscillating changes in attribute values.
Example 1
float $pi = 3.1415927;
sin($pi/2)
Returns 1, the sine of pi/2 radians.
Example 2
Ball.translateY = sin(Ball.translateX);
This statement sets Ball’s translateY attribute equal to the sine of its
translateX attribute. If you drag Ball along the X-axis, Ball’s translateY
position moves up and down in a cyclical pattern:
Example 3
To animate Ball to the path of the preceding example, use this expression:
Ball.translateX = time;
Ball.translateY = sin(Ball.translateX);
Ball starts at the origin and moves in the X direction at a rate set by the
incrementing animation time. Its Y translation moves cyclically up and
down according to the return values of the sin function. The sin function
uses translateX, and therefore indirectly, time, as its argument.
As time increases from 0 to 6.283 seconds, the sin function returns values
that change in fine increments from 0 to 1 to -1 to 0. The value 6.283 is 2
times the value of pi. The resulting motion resembles a horizontal S-shape:
time = 6.283
(2 * pi seconds)
As time increases beyond 6.283 seconds, the same S-shaped cycle repeats for
each span of 6.283 seconds.
Example 4
Expressions
This expression animates Ball with larger up and down swings:
Ball.translateX = time;
Ball.translateY = sin(Ball.translateX) * 2;
By multiplying sin(Ball.translateX) by a number greater than 1, you increase
the amplitude of the sine wave pattern. The amplitude is half the distance
between the minium and maximum values of the wave.
Amplitude
Example 5
This expression increases how often the sine wave completes a cycle:
Ball.translateX = time;
Ball.translateY = sin(Ball.translateX * 2);
By multiplying Ball.translateX by a number greater than 1, you increase the
frequency of the sine wave pattern. The frequency is how long it takes the
wave to make a complete cycle.
Frequency
Example 6
This expression offsets the wave pattern higher up the Y-axis:
Ball.translateX = time;
Ball.translateY = sin(Ball.translateX) + 2;
By adding 2 to sin(Ball.translateX), the wave pattern starts further up the Y-
axis. You can, of course, also subtract a number to offset the wave pattern
lower on the Y-axis.
Offset of 2
Example 7
The following expression sets a frequency multiplier, amplitude, and offset
of a sine pattern in a single statement:
Ball.translateX = time;
Ball.translateY = (sin(Ball.translateX * 2) * 2) + 2;
Expressions
The following diagram shows which values set the frequency multiplier,
amplitude, and offset.
Frequency multiplier
Amplitude
Offset
Ball.translateY = (sin(Ball.translateX * 2) * 2) + 2;
A general equation showing the factors you can use to create a sine wave
pattern follows:
sind
Returns the sine of an angle specified in degrees.
float sind(float number)
number is the angle, in degrees, whose sine you want.
For more details on how to use the sind function, see the sin function in the
preceding topic. The sind and sin functions do the same operation, but sind
requires its argument in degree measurement units.
Example
sind(90)
Returns 1, the sine of 90 degrees.
tan
Returns the tangent of an angle specified in radians.
float tan(float number)
number is the angle, in radians, whose tangent you want.
For any right triangle, the tangent of an acute angle is the following ratio:
opposite A
tan θ = ----------------------- = ---
adjacent B
Y Y
C
A θ
θ B
B X X
A
C
The ratio depends only on the size of the angle and not on the size of the
triangle. This constant ratio is called the tangent of the measure of the angle.
Example
tan(1)
Returns 1.557.
tand
Returns the tangent of an angle specified in degrees.
float tand(float number)
number is the angle, in degrees, whose tangent you want.
For more details on the tand function, see the tan function in the preceding
topic. The tand and tan functions do the same operation, but tand requires
its argument in degree measurement units.
Example
tand(45)
Returns roughly 1, the tangent of 45 degrees.
Expressions
acos
Returns the radian value of the arc cosine of a number. The arc cosine is the
angle whose cosine is the specified number. The returned value is from 0 to
pi.
float acos(float number)
number is the cosine of the angle, and must be from -1 to 1.
Example
acos(1)
Returns 0.
acos(-0.5)
Returns 2.0944 radians.
acosd
Returns the degree value of the arc cosine of a number. The arc cosine is the
angle whose cosine is the specified number. The returned value is from 0 to
180.
float acosd(float number)
number is the cosine of the angle, and must be from -1 to 1.
Example
acosd(1)
Returns 0 degrees.
acosd(-0.5)
Returns 120 degrees.
asin
Returns the radian value of the arc sine of a number. The arc sine is the angle
whose sine is the specified number. The returned value is from -pi/2 to pi/2.
float asin(float number)
number is the sine of the angle, and must be from -1 to 1.
Example
asin(0.5)
Returns 0.525 radians.
asind
Returns the degree value of the arc sine of a number. The arc sine is the
angle whose sine is the specified number. The returned value is from -90 to
90.
float asind(float number)
number is the sine of the angle, and must be from -1 to 1.
Example
asind(0.5))
Returns 30 degrees.
atan
Returns the radian value of the arc tangent of a number. The arc tangent is
the angle whose tangent is the specified number. The returned value is from
-pi/2 to pi/2.
float atan(float number)
number is the tangent of the angle and can be any value.
Example
atan(1)
Returns 0.785.
atand
Returns the degree value of the arc tangent of a number. The arc tangent is
the angle whose tangent is the specified number. The returned value is from
-90 to 90.
Expressions
float atand(float number)
number is the tangent of the angle and can be any value.
Example
atand(1)
Returns 45 degrees.
atan2
Returns the radian value of the arc tangent of specified X and Y coordinates.
The arc tangent is the angle from the X-axis to a line passing through the
origin and a point with coordinates X,Y. The returned angle is in radians,
from -pi to pi, excluding -pi.
float atan2(float Y, float X )
X is the X coordinate of the point.
Example
atan2(1,1)
Returns 0.785 radians.
atan2d
Returns the degree value of the arc tangent of specified X and Y coordinates.
The arc tangent is the angle from the X-axis to a line passing through the
origin and a point with coordinates X,Y. The returned angle is in degrees,
from -180 to 180, excluding -180.
float atan2d(float Y, float X )
X is the X coordinate of the point.
Y is the Y coordinate of the point.
Example
atan2d(1,1)
Returns 45 degrees.
hypot
Returns the magnitude of two-dimensional vector from the origin to a point
with coordinates X, Y.
Y hypot
(X,Y)
As shown in the preceding figure, the hypot function returns the radius of a
circle whose center is at one end of a right triangle’s hypotenuse and
perimeter is at the other end of the hypotenuse.
The following equation gives the magnitude of the vector:
2 2
x +y
Example
hypot(3,4)
Returns 5.
Vector functions
The following functions do operations with vectors. The functions take
vector arguments and return floating point numbers or vectors.
Expressions
angle
Returns the radian angle between two vectors.
Vector1
Angle
Vector2
Example
angle(<<2,-1,1>>,<<1,1,2>>)
Returns 1.0472 radians, which equals 60 degrees.
cross
Returns the cross product of two vectors.
For two vectors, the cross product returns the vector that’s normal to the
plane defined by the two vectors.
Vector1
Vector2
Cross product
Example
cross(<<1,2,-2>>,<<3,0,1>>)
Returns <<2, -7, -6>>.
dot
Returns the floating point dot product of two vectors. The dot product takes
two vectors as arguments and returns a scalar value.
float dot(vector vector1, vector vector2)
If the dot product returns 0, the two vectors are perpendicular.
vector1 is one of the vectors.
vector2 is the other vector.
Example
dot(<<1,2,-2>>,<<3,0,1>>)
Returns 1. The dot product of this example is (1 * 3) + (2*0) + (-2*1), which
equals 1.
mag
Returns the magnitude of a vector. This is the length of the vector.
Y-axis
Expressions
Z
X <<X, Y, Z>>
X-axis
Z-axis
Magnitude
The mag function converts a vector into a floating point number using the
following formula.
2 2 2
x +y +z
Example
mag(<<7,8,9>>)
Returns 13.928.
2 2 2
7 + 8 + 9 = 13.928
rot
Returns a vector that represents the position of a point after it’s rotated a
specified number of radians about a specified axis. Rotation is counter-
clockwise as viewed downward from the axis end position.
Position of point
before rotation
Angle
Position of point
after rotation
Axis
Example 1
rot(<<3,3,0>>,<<1,0,0>>,0.5)
Returns <<3, 2.633, 1.438>>. This is a vector representing the position of
point <<3,3,0>> after rotating it 0.5 radians around the axis represented by
<<1,0,0>>.
Example 2
particleShape1.position = rot(position,<<0,1,0>>,0.1);
Suppose your scene has a single-particle object at position <<4,6,0>>, and
you wrote the above runtime expression for its particle shape node. When
you play the scene, the particle rotates in a circular pattern around the Y-axis
(the axis represented by <<0,1,0>>).
In each frame, the particle’s position rotates 0.1 radian, roughly 5.7 degrees.
Motion
Particle
Expressions
unit
Returns the unit vector corresponding to a vector.
The unit vector has the same direction as the specified vector, but with a
magnitude of 1.
vector unit( vector vector)
vector is the vector whose unit vector you want.
Example
unit(<<1,1,1>>)
Returns <<0.577, 0.577, 0.577>>.
Y
<<1, 1, 1>>
Conversion functions
The following functions convert color scheme values or angle
measurements.
deg_to_rad
Returns the radian equivalent of a degree value. One radian equals roughly
57.29578 degrees.
float deg_to_rad( float degrees )
degrees is the degree angle you want to convert to radians.
Example
deg_to_rad(90)
Returns 1.571, which is the same as pi/2.
rad_to_deg
Returns the degree equivalent of a radian value. One radian equals roughly
57.29578 degrees.
float rad_to_deg(float radians)
radians is the radian angle you want to convert to degrees.
Examples
rad_to_deg(1)
Returns 57.296.
float $pi = 3.1415927;
rad_to_deg($pi)
Returns 180.
hsv_to_rgb
Converts an HSV vector to an RGB vector.
vector hsv_to_rgb(vector hsv)
hsv is a vector representing the hue, saturation, and value components.
Example
hsv_to_rgb(<<1,0.5,0.6>>)
Returns <<0.6, 0.3, 0.3>>.
Tip
To see the relationship between HSV and RGB color components, enter the
Expressions
MEL command colorEditor at the Command Line. This displays the Color
Chooser window.
In the window’s hexagonal color wheel, drag the pointer to a color of
interest. The edit boxes in the window list the color’s values for hue,
saturation, and value—and their counterpart red, green, and blue values.
Note, however, that the Hue value in the Color Chooser has a range of 0 to
360, while the H component of an HSV vector has a corresponding
proportional range of 0 to 1.
When you launch the Color Chooser by entering colorEditor, it’s useful only
for learning about color. You can’t use it to change the color of objects in
your scene.
rgb_to_hsv
Converts an RGB vector to an HSV vector.
Example
rgb_to_hsv(<<0.6,0.6, 0.6>>)
Returns <<0, 0, 0.6>>.
Array functions
The following functions work with integer, floating point, and vector arrays.
If you need more information, see a reference book on the C programming
language.
clear
Empties the array’s contents, freeing all memory reserved for the array.
After you clear an array, its size is 0. When you no longer need to use an
array, use the clear function to free memory.
int clear(array array)
array is the name of the array you want to clear.
The clear function returns 1 if the function succeeds, 0 if it fails. The return
value is not typically used in expressions.
Example
int $myInts[] = {1,2,3,4,5,6};
print("size of $myInts is: "+size($myInts)+"\n");
clear($myInts);
print("size of $myInts is: "+size($myInts)+"\n");
The third statement above clears the array $myInts.
The second and fourth statements display the following text in the Script
Editor:
size of $myInts is: 6
size of $myInts is: 0
size
Returns the number of elements in an array or the number of characters in a
string.
int size(array array)
int size(string string)
array is the name of the array whose size you want.
string is the string whose number of characters you want.
Example 1
string $s = "Hello";
$stringlen = size($s);
The size($s) function returns 5, then the statement assigns 5 to $stringlen.
Example 2
int $myInts[] = {1,2,3,4,5,6};
$numInts = size($myInts);
The size($myInts) function returns 6, then the statement assigns 6 to
$numInts.
Expressions
sort
Returns an array sorted in alphabetical or ascending numerical order. The
returned array has the same number and type of elements as the original
array.
array sort(array array)
Example 1
int $myInts[] = {3,6,1,4,2,5};
int $afterSorting[] = sort($myInts);
print("After sorting, the array contains:\n");
for ($i = 0; $i < 6; $i = $i + 1)
{
print($afterSorting[$i]+"\n");
}
The sort function sorts the elements of $myInts in ascending order. The
following appears in the Script Editor:
After sorting, the array contains:
1
2
3
4
5
6
Example 2
string $myName[] = {"Peewee","Michael","Kennedy"};
string $afterSorting[] = sort($myName);
print("After sorting, the array contains:\n");
for ($i = 0; $i < 3; $i = $i + 1)
{
print($afterSorting[$i]+"\n");
}
The sort function sorts the elements of $myName in alphabetical order. The
following appears in the Script Editor:
After sorting, the array contains:
Kennedy
Michael
Peewee
gauss
Returns a random floating point number or vector. The number returned
falls within a Gaussian (bell curve) distribution with mean value 0.
float gauss(float stdDev)
vector gauss(float XstdDev, float YstdDev)
vector gauss(vector stdDevVector)
stdDev specifies the value at which one standard deviation occurs along the
distribution. This gives a one-dimensional Gaussian distribution.
XstdDev and YstdDev specify the values for one standard deviation. This
gives a two-dimensional Gaussian distribution in the XY plane. The right
component of the vector returned is 0.
stdDevVector specifies the vector component values for one standard
deviation. This gives a three-dimensional distribution.
Expressions
To control the random values returned by this function, see “seed” on page
246.
Example
gauss(5)
Returns a random floating point value such as 0.239.
If you were to execute gauss(5) repeatedly and chart the values returned,
they would occur roughly with this frequency:
Mean
-5 0 5
Value returned
If you were to execute gauss(2) repeatedly, return values would occur with
this frequency:
Mean
-2 0 2
Value returned
noise
Returns a random number from -1 to 1 according to a Perlin noise field
generator.
float noise(float number)
float noise(float xnum, float ynum)
float noise(vector vector)
number specifies a number that generates a random number. This gives a
one-dimensional distribution of return values.
xnum and ynum specify numbers for generating a random number. This
gives a two-dimensional distribution of return values.
vector specifies a vector for generating a random number. This gives a three-
dimensional distribution of return values.
If you execute this function with the same argument value repeatedly, the
function returns the same random value each time it executes.
If you execute this function with an argument value that steadily increases
or decreases in fine increments over time, the function returns random
values that increase and decrease over time.
Example 1
Expressions
noise(time)
Returns a value between -1 and 1 each time the expression executes as an
animation plays. Because time increases in fine increments, the values
returned increase and decrease in smooth, yet random, patterns. If you were
to chart the values returned over a period of time, they might occur as in this
figure:
1
Return
value 0
-1
noise(time) as animation plays
Example 2
noise(frame)
Returns a value between -1 and 1 each time the expression executes as an
animation plays. Because frame increases in larger increments, the values
returned increase and decrease in rougher patterns. If you were to chart the
values returned over a period of time, they might occur as in this figure:
1
Return
value 0
-1
noise(frame) as animation plays
The value returned by noise(frame) and noise(time) is the same when frame
contains the same number as time. For example, when frame equals 10,
noise(frame) returns the same value that noise(time) returns when time is 10.
dnoise
Returns a vector with each component containing a random number from -1
to 1. It works like the noise function except it expects and returns a vector
argument. The returned vector represents the gradient of the noise field in
three dimensions.
vector dnoise(vector argument)
argument specifies a vector for generating a random number. This gives a
three-dimensional distribution of return values.
See the noise function for more details on dnoise operation.
Example
dnoise(<<10,20,-30>>)
Returns <<-0.185, 0.441, 0.686>>.
rand
Returns a random floating point number or vector within a range of your
choice.
float rand(float maxnumber)
float rand(float minnumber, float maxnumber)
vector rand(vector maxvector)
vector rand(vector minvector, vector maxvector)
maxnumber specifies the maximum number returned (in the first syntax
format listed above). The minimum number returned is 0. In other words,
the returned value will be a random number between 0 and maxnumber.
minnumber and maxnumber specify the minimum and maximum numbers
returned.
maxvector specifies the maximum value for each component of the vector
returned. The minimum value is 0. Each component returned is a different
random number.
minvector and maxvector specify the minimum and maximum value for each
component of the vector returned.
To control the random values returned by this function, see “seed” on page
Expressions
246.
Example 1
rand(5)
Returns a random floating point number between 0 and 5, for example,
3.539.
Example 2
rand(-1,1)
Returns a random floating point number between -1 and 1, for example,
0.452.
1
Return
value 0
-1
rand(1,-1) as animation plays
Example 3
rand(<<1,1,1>>)
Returns a random vector in which each component is between 0 and 1, for
example, <<0.532, 0.984, 0.399>>.
Example 4
rand(<<1,1,1>>,<<100,200,300>>)
Returns a random vector in which the left component is between 1 and 100,
the middle component is between 1 and 200, and the right component is
between 1 and 300. An example is <<81.234, 49.095, 166.048>>.
sphrand
Returns a random vector value that exists within a spherical or ellipsoidal
region of your choice. An ellipsoid is a sphere scaled along its X-, Y- or Z-
axes.
vector sphrand(float radius)
vector sphrand(vector vector)
radius is the radius of a sphere in which the returned vector exists.
vector is the radius of an ellipsoid along the X-, Y-, and Z-axis.
To control the random values returned by this function, see “seed” on page
246.
Example 1
sphrand(1)
Returns a vector whose randomly selected coordinates reside within an
imaginary sphere centered at the origin and with a radius of 1. An example
returned vector is <<0.444, -0.427, 0.764>>.
radius
Example 2
sphrand(<<2,1,1>>)
Returns a vector whose coordinates reside within an ellipsoid centered at the
origin and with a radius of 2 along the X-axis, 1 along the Y-axis, and 1 along
the Z-axis.
Expressions
Radius in Z
2
1
1 Radius in X
Outer bound of
returned value
Radius in Y
seed
Sets a seed value the gauss, rand, and sphrand functions use to generate
random numbers. If you assign a value to the seed then execute the gauss,
rand, or sphrand function repeatedly, an identical sequence of random
numbers is generated. For clarification, see the example below and
“Reproducing randomness” on page 123.
int seed(int number)
number sets an arbitrary number to be used as the seed value.
Example
Suppose you create a NURBS sphere named Ball then enter this expression:
Ball.translateX = rand(5);
Expressions
Frame Value
1 4.501
2 3.863
3 3.202
4 3.735
5 2.726
6 0.101
Each time you rewind and play the animation, translateX receives the same
sequence of random values.
For different seed values, the sequence of numbers returned will differ. You
can’t predict the values in the number sequence based on the value of the
seed.
Frame Value
1 4.725
2 2.628
3 0.189
4 0.004
5 4.834
6 0.775
By changing the seed function’s value, you change the sequence of random
numbers generated.
A common mistake while using the seed function follows:
seed(1);
Ball.translateX = rand(5);
When you rewind the animation, Ball’s translateX attribute receives the
value 4.501. When you play the animation, the translateX attribute receives
4.501 each time the expression executes.
Because you assign a value (1) to the seed before each execution of rand(5),
you initialize the random number sequence. The rand(5) function therefore
returns the first value of the number sequence each time it executes.
Important
When you set a seed value in an expression or MEL script, the seed value
affects the rand, sphrand, and gauss functions in other expressions and
MEL scripts. Such functions are affected by this seed value in all scenes
you open subsequently in the current work session.
Curve functions
The step functions let you make smooth, incrementing transitions between
values.
linstep
Returns a value from 0 to 1 that represents a parameter’s proportional
distance between a minimum and maximum value. This function lets you
increase an attribute such as opacity from 0 to 1 linearly over a time range.
float linstep(float start, float end, float parameter)
start and end specifies the minimum and maximum values.
parameter is the value you want to use to generate the proportional number.
If parameter is less than start, linstep returns 0.
If parameter is greater than end, linstep returns 1.
Example
Suppose you’ve used the Particle Tool to create a collection of particles
named Cloud:
Expressions
Suppose further you’ve added a dyamic per object opacity attribute to Cloud
(see “Working with particle attributes” in Chapter 8). You then write this
runtime expression for Cloud’s particle shape node:
CloudShape1.opacity = linstep(0,5,age);
Age Opacity
0.0417 0.0083
0.0833 0.0166
0.125 0.025
0.1667 0.0333
0.2083 0.0417
2.5 0.5
1.0 0.2
3.75 0.75
5 1
5.041 1
5.083 1
10 1
As the table shows, the opacity increases in linear increments for the first 5
seconds of the object’s age. At the midpoint of the specified 0 to 5 second age
range, the opacity is 0.5. At 3/4 of the way between 0 and 5 seconds, the
opacity is 0.75. At 5 seconds of the object’s age, opacity is 1. After 5 seconds,
the opacity stays at 1.
opacity
0 5
age (in seconds)
Expressions
1
opacity
0 5 10
age (in seconds)
opacity
0 5
age (in seconds)
smoothstep
Returns a value from 0 to 1 that represents a parameter’s proportional
distance between a minimum and maximum value. The smoothstep function
lets you increase an attribute such as opacity from 0 to 1 gradually, but
nonlinearly, over a time range.
The smoothstep function works like the linstep function, except it increases
values more quickly near the middle values between the minimum and
maximum value. The function uses hermite interpolation between minimum
and maximum values.
float smoothstep(float start, float end, float parameter)
start and end specifies the minimum and maximum values.
parameter is the value you want to use to generate the smoothstep number.
If parameter is less than start, linstep returns 0.
If parameter is greater than end, linstep returns 1.
parameter
smoothstep linstep
start end
Example
Suppose you’ve used the Particle Tool to create a collection of particles
named Cloud:
Expressions
Suppose also you’ve added a dynamic per object opacity attribute to Cloud
(see “Working with particle attributes” in Chapter 8). You then write this
runtime expression for Cloud’s particle shape node:
CloudShape1.opacity = smoothstep(0,5,age);
opacity
0 5
age (in seconds)
hermite
Returns values along a hermite curve. You can use the hermite function, for
instance, to move a particle object’s position smoothly along a curve. As the
examples in the following pages show, you can create various curve shapes
by altering the arguments to the hermite function.
vector hermite(vector start, vector end, vector tan1, vector tan2, float parameter)
float hermite(float start, float end, float tan1, float tan2, float parameter)
start is the start point of the curve.
end is the end point of the curve.
tan1 is the tangent vector that guides the direction and shape of the curve as
it leaves the start point of the curve. The vector’s position starts at the start
point of the curve.
tan2 is the tangent vector that guides the direction and shape of the curve as
it approaches the end point of the curve. The vector’s position starts at the
end point of the curve.
parameter is an floating point value between 0 and 1, for example, the value
returned by a linstep function.
In the second format, the arguments and return values work in a single
dimension.
Example 1
Suppose you create an object named dust made of one particle at the origin.
To guide its motion along a short upward-bound curve for the first four
seconds of animation, you can write the following runtime expression:
dust.position = hermite(<<0,0,0>>,<<2,2,0>>,
<<3,0,0>>, <<0,3,0>>, linstep(0,4,time));
When you play the animation, the particle moves from the start point
<0,0,0> along a curve to the end point <2,2,0>. The tangent vector <3,0,0>
sets the curve’s direction and shape as it leaves the start point. The tangent
vector <0,3,0> sets the curve’s direction and shape as it approaches the end
point.
From zero to four seconds of animation play, the particle moves along the
curve as defined by the linstep function. (See page 249 for details on linstep.)
The function arguments and resulting path of the object follow:
Y
tan2 = <<0,3,0>>
Expressions
end = <<2,2,0>>
Object’s path
Example 2
Suppose you change the third argument of the previous example expression
to <<6,0,0>>:
dust.position = hermite(<<0,0,0>>,<<2,2,0>>,
<<6,0,0>>, <<0,3,0>>, linstep(0,4,time));
The slope of the path curve steepens because of the longer tan1 vector:
Y tan2 = <<0,3,0>>
end = <<2,2,0>>
Object’s path
X
start = <<0,0,0>> tan1 = <<6,0,0>>
Example 3
The following expression moves dust in an S pattern:
dust.position = hermite(<<0,0,0>>,<<2,0,0>>,
<<0,3,0>>, <<0,3,0>>, linstep(0,4,time));
The tan1 vector <<0,3,0>> sets the direction of the curve from the start point
to a positive Y direction. The tan2 vector <<0,3,0>> sets the direction of the
curve to a positive Y direction as it approaches the end point.
Values between the start and end point curves are interpolated to form an S
pattern.
Example 4
Suppose you change the fourth argument of the previous example
expression to <<0,-3,0>>:
dust.position = hermite(<<0,0,0>>,<<2,0,0>>,
<<0,3,0>>, <<0,-3,0>>, linstep(0,4,time));
The dust particle moves in a pattern resembling a half-circle:
tan1 = <<0,3,0>>
Expressions
tan2 = <<0,-3,0>>
The tan1 vector <<0,3,0>> sets the direction of the curve from the start point
to a positive Y direction. The tan2 vector <<0,-3,0>> sets the direction of the
curve to a negative Y direction as it approaches the end point.
Example 5
Suppose you change the third argument of the preceding example to
<<0,10,0>>:
dust.position = hermite(<<0,0,0>>,<<2,0,0>>,
<<0,10,0>>, <<0,-3,0>>, linstep(0,4,time));
Y
tan1 = <<0,10,0>>
tan2 = <<0,-3,0>>
Because of the longer tan1 vector, the slope of the path curve steepens as it
rises from the start point. Because the tan2 vector has a smaller Y magnitude
than the Y magnitude of the tan1 vector, the slope of the path curve is flatter
as it approaches the end point. The curve’s rise in the Y direction is greater
than the previous example because the magnitude of tan1’s Y component is
larger (10 instead of 3).
General commands
The following functions do various actions in Maya.
eval
Executes a MEL command.
string eval(string command)
command is either a command string enclosed in quote marks or a string
variable containing a command.
The returned value contains command output returned by the command’s
execution.
Example 1
eval("select -cl")
Executes the command select -cl, which deselects all objects in the scene.
Though the return value is not used in this example, it contains the
command output.
Example 2
string $cmd = "select -cl";
Expressions
eval($cmd);
The first statement assigns the command string select -cl to the string variable
$cmd. The second statement executes the contents of $cmd, which is the
command select -cl.
Example 3
string $mycommand = "sphere";
eval($mycommand+"-r 5");
The first statement assigns the string sphere to the variable $mycommand.
The second statement appends -r 5 to the string sphere and executes the
complete command sphere -r 5. This creates a sphere with a radius of 5 grid
units.
Example 4
string $a[];
$a = eval("ls -lights");
print($a);
The first statement defines an array of strings named $a. The second
statement executes the MEL command ls -lights, then assigns the command’s
output to array $a. The third statement displays the contents of $a to the
Script Editor as follows:
ambientLightShape1
directionalLightShape1
Note that each line of command output appears on a new line. Each
command output line is an array element. Maya formats array output with
each array element on a new line.
Example 5
Suppose you’ve created a MEL script file named bunk.mel in your Maya
scripts directory and it contains this procedure:
global proc string bunk()
{
string $fog;
if (rand(2) < 1)
$fog = "particle";
else
$fog = "sphere";
return $fog;
}
Further suppose you create this expression:
string $name = bunk();
eval($name);
print($name);
The first expression statement executes the bunk() procedure in the
bunk.mel script file. In the bunk procedure, the if-else statement generates a
random floating point value between 0 and 2, then compares its value to 1.
If the value is less than 1, the statement assigns the MEL command string
particle to $fog. If the value is greater than 1, $fog receives the command
string sphere.
The procedure finishes executing and passes the value of $fog back to the
calling procedure, bunk() in the expression. This assigns the command string
to the variable $name.
The eval function executes the command string stored in the $name. For
example, the statement might execute particle, which creates a particle at the
origin of the workspace.
The fourth statement displays the contents of $name, for example, particle.
The expression executes each frame and creates a new particle or sphere.
print
Displays text in the Script Editor. You can use this function to display the
contents of attributes and variables. This is helpful for debugging an
expression.
print(string text)
print(vector number)
print(float number)
print(int number)
print(array number)
Expressions
text is either a string enclosed in quote marks or an attribute name or string
variable containing text.
number is a number without the quote marks. Numerical arguments display
as strings.
There is no returned value for this function.
Note the following display considerations.
• You can format displayed text with standard C language escape characters.
For example, you can create a new line with “\n” or a tab character with
“\t” in the argument.
• Displaying a floating point value shows the number with up to 10 digits to
the right of the decimal point, for example 0.3333333333.
• Insignificant 0 digits are truncated from floating point numbers. For
example, floating point number 2.0 is displayed as 2.
int "3.14" 3
As shown in the last row of the table, if a variable is assigned a string that
starts with a nonnumerical character, Maya converts the string to 0.
• For a nonparticle expression consisting of only print statements, Always
Evaluate must be on in the Expression Editor for the expression to execute.
Examples
print(time);
print("\n");
The first statement displays the value of time. The second statement displays
a new-line character after the value of time, so the time appears on a
separate line in the Script Editor.
float $f = 3.14159;
print($f);
Displays the floating point number 3.14159.
string $s = "Hello There";
print($s);
Displays the string Hello There.
vector $v;
$v = <<1.2,2.3,3.4>>;
print($v);
Displays the vector as 1.2 2.3 3.4.
string $a[];
$a = eval("ls -lights");
print($a+" are the lights in my scene.\n");
The print function causes an error message because you cannot use the +
Expressions
operator with a string array.
system
Passes a UNIX command to the shell where you launched Maya.
int system( string command)
command is either a command string enclosed in quote marks or a string
variable containing a command.
The returned value is the output resulting from the command’s execution.
Example
string $cmdout;
$cmdout = system("date");
print($cmdout+"\n");
Executes the UNIX date command, which outputs your workstation’s date
and time to the $cmdout variable. The final statement displays the date in
the Script Editor.
pwd fwrite
source fread
trace filetest
warning
whatIs
degrees 29
converting to radians 129,
E executing
MEL commands in
234 e raised to power 214 expressions 137
deleting Edit button 22 MEL commands with eval
attribute names 131 function 259
editing expressions
expressions 112, 134 MEL procedures in
in text field 99, 105
text from expressions 105 expressions 139
else keyword 38 nonparticle expressions 118
depthSort 197
else-if statements 71 UNIX commands in
discarded remainders in data type
emitted particles expressions 263
conversions 146
age of 149 execution
disconnectAttr command 132
assigning lifespanPP for 183 slow expression 127
disconnecting an attribute 132 creation expression execution exp function 214
displaying and 149
exponential functions 214
attribute contents 123 working with 183
disconnected attributes 132 Expression Editor
English common names for
text 261 starting 13
attributes 114
variable contents 123 equal to (==) operator 36
dnoise function 242 errors
do loop 78 common expression 95
dollar sign ($) in variable comparing floats with the ==
names 59, 73 operator 89
dot function 231 from wrong data types in
dot product 231 functions 208
in flow control statements 88
dot product operator 64
logic 95
double angle brackets 53, 73,
message format of 95
180, 193
syntax 36, 73, 95
dynamic attributes 49
where they appear 96
adding to object 49, 50, 161
eval function 259
dynamic per object attribute
event 198
example assignment to
lifespan 167 event attribute 184
when collision count
dynamic per particle attribute
increases 187
example assignment to
lifespanPP 164 eventCount 198
dynamics eventCount attribute 184
changing start frame 149 eventTest 198
how often Maya eventTest attribute 184
evaluates 149, 152 examining two or more
Dynamics Controller 149, 152 expressions 106
dynamicsWeight 198
dynamicsWeight attribute 178
goalWeight 198
gravity field
jot text editor 107
M
acceleration’s effect on 177 mag function 231
K magnitude of a vector 67, 231
mass 199
H keyframes
eliminating expression to matrix data type 55
half-circle use 122 max function 212
creating motion with hermite keywords in expressions 76 maxCount 199
function 257 measurement units 127
hermite function 254 MEL commands 45, 46
HSV conversion to RGB 235 L executing with eval
hsv_to_rgb function 235 function 259
levelOfDetail 199 using alone in
hypot function 229
lifespan 198 statements 137
lifespan attribute 161 using with eval function 138
example assignment in using within single
I creation expression 167 quotes 138
if statements 32, 34, 69 Lifespan button 161 MEL procedures
lifespanPP 199 using in expressions 138
if-else abbreviation 86
lifespanPP attribute 161, 164 MEL scripts 46
if-else statements 38, 39, 70
assigning for emitted millimeters 128
incandescence 198
particles 183 min function 212
incandescencePP 198
limit functions 209 mixed data types
increment operations and
unexpected values 142 lineWidth 199 using with arithmetic
linking attributes 11, 15, 26 operators 145
inheritFactor 198
linstep function 249 modulus operator (%) 63, 182,
initial state attributes 158, 162,
comparison with 192
163
smoothstep 253 risk of using with floats 182
creation expression
execution 150 listAttributes MEL command 163 motion
naming convention 163 log base 10 214 creating jittery 175
saving values for 158 creating smooth, random 175
log function 214
input to expressions 135 multiCount 199
logic errors 95
integers 52, 57 multiRadius 199
logical operators 67
handling as floating point 65 && 67
internal conversion of units 127 || 67
isDynamic 198 long attribute names 114 N
looping errors 88 natural logarithm 214
new line characters in print
J statement 261
joining text in strings 262
velocity attribute
assigning with creation
expression 150
assigning with runtime
expression 153, 154
field’s effect on 175
working with 175
vi text editor 107
vim text editor 107
visibleInReflections 201
visibleInRefractions 201
W
while loop 77
white space in expressions 74
WINEDITOR setting 109, 110
X
xemacs text editor 107