エクスプレッション
エクスプレッションによるアニメーション
エクスプレッションの機能を使用すると、ノードのアトリビュートを数式・プロシージャなどでアニメーションさせることができます。
エクスプレッションを定義・編集するには、通常 エクスプレッション エディタ を使用しますが、
ここでは、 MEL の expression コマンドを使用して実行する方法を紹介します。
expression コマンド
expression コマンドでは、 -string フラグの右にエクスプレッションを定義します。
エクスプレッションには、数式だけでなく変数を使用したり
if, while, for, switch
などの制御構造や、
自分で作ったプロシージャも使用できます。
ですから MEL スクリプトで表現できることなら、
どんな複雑なアニメーションでも実行できます。
エクスプレッションのキーワード
エクスプレッションでは、以下の特別なキーワードを使用して式・プロシージャを作ってゆきます。
これらのキーワードをエクスプレッションで使用する時は、
MEL 変数のように $ をつける必要はありません。
- frame
- 現在のフレーム数
- time
- 現在の時間
NTSC に設定してあれば 1 秒あたり 30 フレームになっているので
1 フレームで 1/30 = 0.033 秒時間が進みます。
エクスプレッション使用時の注意
エクスプレッションの記述方法は、
MEL に似ていますが違うところも存在します。
エクスプレッションを作成するときに、注意しておくべきことを挙げて起きます。
- コメントの /* */ は使用できません。
// の形のコメントは使用可能です。
- 計算の単位は、なるべくセンチメートル、ラジアン、秒を使用します。
Maya の内部計算は、センチメートル、ラジアン、秒の単位を使用して行われているので、
それ以外の単位を使用すると変換に計算時間がかかります。
- アトリビュート値の設定に setAttr コマンドは使用しません。
エクスプレッション内で、アトリビュートに値を設定するためには、
以下で解説する方法を使います。
expression コマンドのオプション
- -string string
- エクスプレッションの式・プロシージャなどを定義する string を指定します。
- -name string
- string を、このエクスプレッションの名前にします。
- -object string
- string を、このエクスプレッションで使うノードの名前にします。
このオプションで指定されたノードの名前は、エクスプレッションの中で省略できます。
- -query
- -string フラグや -name フラグと共に使用して、それらの値を返します。
- -edit
- -string フラグや -name フラグと共に使用して、それらの値を変更します。
expression コマンドの使用例 1
- を表示しておいてください。
以下のコマンドは、
のインプットウィンドウから実行します。
- 適当な名前で球体を 1 個作ります。
ここでは、sphere1 という名前にしておきます。
sphere -n sphere1;
- エクスプレッションを expression コマンドで定義します。
以下のコマンドは、 sphere1 のアトリビュート translateX を sin 関数で変化させます。
expression -string "sphere1.tx = sin(time);";
このコマンドを実行した後、
に表示される
// 結果: の右の expresson1
が、このエクスプレッションの名前になります。
- この後、アニメーションを実行すると、球体が X 軸方向に -1.0 から 1.0 の間を振動します。
- 以上のエクスプレッションでは、
移動距離が短くてアニメーションさせても動きが良く分からないので、
エクスプレッションの定義を変更してみましょう。
そのために、-edit フラグを使用して、以下のようにコマンドを実行します。
コマンドの最後の expression1 は変更するエクスプレッションの名前です。
expression -edit -string "sphere1.tx = 5 * sin(time);" expression1;
expression コマンドの使用例 2
エクスプレッションは、 エクスプレッション エディタ によって設定できますが、
大量のオブジェクトに設定しようとするとたいへんです。
そのような場合には、 MEL スクリプトを使用すると効率良く設定できます。
以下の MEL スクリプトは、指定された個数のコーンを作って、
それぞれのコーンにエクスプレッションを設定します。
このエクスプレッションを、
すべてのコーンが少しづつ違うアニメーションをするものにしてみましょう。
- 以下のプロシージャを makeExpression1.mel と言う名前でファイルに書き込みます。
global proc makeExpression1(int $num)
{
int $i;
for($i = 0; $i < $num; $i++)
{
string $name[] = `cone`;
move ($i * 2) 0 0;
float $val = $i * 0.3;
expression -object $name[0] -string ("sy = 3 * sin(time + " + $val + ");");
}
}
- で makeExpression1.mel を読み込みます。
- で以下のコマンドを実行します。
makeExpression1(10);
コ−ンが 10 個現れて、それぞれに違うエクスプレッションが設定されます。
アニメーションのレンダリング例
スクリプトの解説
-
global proc makeExpression1(int $num)
- makeExpression1 という名前のプロシージャを宣言です。
引数の $num は作られるコーンの個数を表します。
-
for($i = 0; $i < $num; $i++)
- $i を 0 から 1 づつ増やして、
$num - 1 になるまで、 $num 回 for 文を繰り返し実行します。
-
$name = `cone`;
- コーンを作り、その名前を $name に代入しておきます。
-
move ($i * 2) 0 0;
- 作ったコーンを X 軸方向に $i * 2 だけ移動します。
この式の 2 はコーンの高さ(底から頂点まで)を表します。
また、コマンドの途中に ( ) があると、
その ( ) の中を先に計算(実行)してからコマンド全体を実行します。
-
$val = $i * 0.3;
- コーンの動きを少しづつずらすために、
$val に $i * 0.3 の結果を代入しておきます。
この式の 0.3 は適当な値なので、別の値にしてもかまわいません。
-
expression -object $name[0] -string ("sy = 3 * sin(time + " + $val + ");");
- エクスプレッションを定義しています。
コーンの名前が入っている $name[0] に
-string フラグ以下の式を定義しています。
ここでは、MEL スクリプトで定義された変数 $val の値を式に取り込んで、
以下のような式をエクスプレッションとして定義します。
"sy = 3 * sin(time + ここに $val の値をあてはめる);"
しかし、以下のように直接 $val を式の中に記述するとエラーになります。
"sy = 3 * sin(time + $val);"
これは、$val が MEL スクリプトにおけるプロシージャ内の変数なので、
エクスプレッション内から参照できないからです。
ですから、ここの expression コマンドのように、
少し複雑な記述をする必要があります。
このように、エクスプレッションの定義が複雑なので、
-string 以下の部分が、どのように実行されるか以下に解説しておきます。
- ("sy = 3 * sin(time + " + $val + ");")の外側の括弧内は、
3 つの部分に分かれます。
- "sy = 3 * sin(time + "
- $val
- ");"
この式の sy (スケール Y) は
-object フラグで指定されたコーン($name[0])のアトリビュートです。
- まず、$val の部分が $val = $i * 0.3;
で計算された値に置き換えられます。
- それから、上の 3 つの部分が文字列を連結する演算子
+ によって 1 つの文字列になります。
その文字列がエクスプレッションの式として、
$name[0] で表されるコーンに割り当てられます。
具体的な例として $i が 2 の場合(3 個目のコーンの場合)に、
どのように式が作られるかを見てみましょう。
-
$val = $i * 0.3; の部分を計算し、
$val に 2 * 0.3 の計算結果 0.6 を代入します。
- expression コマンドの -string フラグ以下の ("sy = 3 * sin(time + " + $val + ");") は
("sy = 3 * sin(time + " + 0.6 + ");") となります。
- 式の 3 つの部分
- "sy = 3 * sin(time + "
- 0.6
- ");"
が + によって 1 つの文字列に連結されます。
- 連結された文字列が、 3 個目のコーンのエクスプレッションとして定義されます。
sy = 3 * sin(time + 0.6 )
もし引数 $num が 10 ならば 10 個のコーンに対して、それぞれ以下のエクスプレッションが定義されます。
- 1 個目 sy = 3 * sin(time + 0.0 )
- 2 個目 sy = 3 * sin(time + 0.3 )
- 3 個目 sy = 3 * sin(time + 0.6 )
- 4 個目 sy = 3 * sin(time + 0.9 )
- 5 個目 sy = 3 * sin(time + 1.2 )
- 6 個目 sy = 3 * sin(time + 1.5 )
- 7 個目 sy = 3 * sin(time + 1.8 )
- 8 個目 sy = 3 * sin(time + 2.1 )
- 9 個目 sy = 3 * sin(time + 2.4 )
- 10 個目 sy = 3 * sin(time + 2.7 )
文字列中に変数の値を挿入
MEL では、上のエクスプレッション式のように、文字列の途中に変数値を当てはめたい事がよくあります。
そういう場合は、以下の順序で書き換えてください。
- 変数を、文字列中の当てはめたい位置に書いておきます。
"sy = 3 * sin(time + $val);"
- 変数の左に " + を、右に + " を追加します。
"sy = 3 * sin(time + " + $val + ");"
- 最後に、最初の " と、最後の " を ( ) で囲みます。
("sy = 3 * sin(time + " + $val + ");")
三角関数について
三角関数はエンジンのピストン運動や、波などのような往復運動をさせたい場合に良く使われます。
Maya で使用できる三角関数の種類には、sin、 cos、 tan、 asin、 acos、 atan などがありますが、
通常は sin と cos で十分でしょう。
三角関数には非常に多くの性質や定理がありますが、エクスプレッションで使用するときには基本的な性質だけわかっていれば良いでしょう。
たとえば、
$a * sin($b * time + $c) + $d
という式があったとすると、以下のような性質があります。
- $a の値が大きくなると波が大きくなり、
小さくなると波が小さくなります。
- $b の値が大きくなると波のスピードが速くなり、
小さくなると波のスピードが遅くなります。
- $c の値によって波の縦方向の位置をずらすことができます。
これによって、アニメーションのタイミングをずらすことができます。
- $d の値によって波の縦方向の位置をずらすことができます。
これによって、計算結果の最大値・最小値が変わります
練習
- 上の makeExpression1.mel を参考にして makeExpression2.mel を作り、スケールのかかる方向を引数によって変えることができるようにしてみましょう。
引数は 2 つで 1 番目の引数 $num は makeExpression1.mel と同じ、2 番目の引数 $axis によってアニメーションの方向を変えます。
global proc makeExpression2(int $num, int $axis)
2 番目の引数 $axis は以下の 1 から 3 の値をとることとします。
(それ以外の値は無視してよいことにしておきます)
- 1
- X 方向にアニメーションさせる。
(スケール X をアニメーション)
- 2
- Y 方向にアニメーションさせる。
(スケール Y をアニメーション)
- 3
- Z 方向にアニメーションさせる。
(スケール Z をアニメーション)
参考
練習課題
Prev | Next
Home | Contents
Mail