エクスプレッション

エクスプレッションによるアニメーション

エクスプレッションの機能を使用すると、ノードのアトリビュートを数式・プロシージャなどでアニメーションさせることができます。
エクスプレッションを定義・編集するには、通常 エクスプレッション エディタ を使用しますが、 ここでは、 MEL の expression コマンドを使用して実行する方法を紹介します。

expression コマンド

expression コマンドでは、 -string フラグの右にエクスプレッションを定義します。
エクスプレッションには、数式だけでなく変数を使用したり if, while, for, switch などの制御構造や、 自分で作ったプロシージャも使用できます。 ですから MEL スクリプトで表現できることなら、 どんな複雑なアニメーションでも実行できます。

エクスプレッションのキーワード

エクスプレッションでは、以下の特別なキーワードを使用して式・プロシージャを作ってゆきます。
これらのキーワードをエクスプレッションで使用する時は、 MEL 変数のように $ をつける必要はありません。

frame
現在のフレーム数
time
現在の時間
NTSC に設定してあれば 1 秒あたり 30 フレームになっているので 1 フレームで 1/30 = 0.033 秒時間が進みます。

エクスプレッション使用時の注意

エクスプレッションの記述方法は、 MEL に似ていますが違うところも存在します。
エクスプレッションを作成するときに、注意しておくべきことを挙げて起きます。

expression コマンドのオプション

-string string
エクスプレッションの式・プロシージャなどを定義する string を指定します。
-name string
string を、このエクスプレッションの名前にします。
-object string
string を、このエクスプレッションで使うノードの名前にします。
このオプションで指定されたノードの名前は、エクスプレッションの中で省略できます。
-query
-string フラグや -name フラグと共に使用して、それらの値を返します。
-edit
-string フラグや -name フラグと共に使用して、それらの値を変更します。

expression コマンドの使用例 1

  1. スクリプト エディタ を表示しておいてください。
    以下のコマンドは、 スクリプト エディタ のインプットウィンドウから実行します。
  2. 適当な名前で球体を 1 個作ります。
    ここでは、sphere1 という名前にしておきます。
    sphere -n sphere1;
    [sphere コマンドの実行]
  3. エクスプレッションを expression コマンドで定義します。
    以下のコマンドは、 sphere1 のアトリビュート translateX を sin 関数で変化させます。
    expression -string "sphere1.tx = sin(time);";
    [expression コマンドの実行前]
    このコマンドを実行した後、 スクリプト エディタ に表示される // 結果: の右の expresson1 が、このエクスプレッションの名前になります。
    [expression コマンドの実行後]
  4. この後、アニメーションを実行すると、球体が X 軸方向に -1.0 から 1.0 の間を振動します。
  5. 以上のエクスプレッションでは、 移動距離が短くてアニメーションさせても動きが良く分からないので、 エクスプレッションの定義を変更してみましょう。
    そのために、-edit フラグを使用して、以下のようにコマンドを実行します。
    コマンドの最後の expression1 は変更するエクスプレッションの名前です。
    expression -edit -string "sphere1.tx = 5 * sin(time);" expression1;
    [expression コマンドの実行前]
    [expression コマンドの実行前]

expression コマンドの使用例 2

エクスプレッションは、 エクスプレッション エディタ によって設定できますが、 大量のオブジェクトに設定しようとするとたいへんです。 そのような場合には、 MEL スクリプトを使用すると効率良く設定できます。

以下の MEL スクリプトは、指定された個数のコーンを作って、 それぞれのコーンにエクスプレッションを設定します。 このエクスプレッションを、 すべてのコーンが少しづつ違うアニメーションをするものにしてみましょう。

  1. 以下のプロシージャを 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 + ");");
    	}
    }
    
  2. ファイル → ソーススクリプト で makeExpression1.mel を読み込みます。
  3. スクリプト エディタ で以下のコマンドを実行します。
    makeExpression1(10);
    コ−ンが 10 個現れて、それぞれに違うエクスプレッションが設定されます。
    [makeExpression1(10) の実行後]
    アニメーションのレンダリング例

スクリプトの解説

global proc makeExpression1(int $num)
makeExpression1 という名前のプロシージャを宣言です。
引数の $num は作られるコーンの個数を表します。
for($i = 0; $i < $num; $i++)
$i を 0 から 1 づつ増やして、 $num - 1 になるまで、 $numfor 文を繰り返し実行します。
$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 以下の部分が、どのように実行されるか以下に解説しておきます。
  1. ("sy = 3 * sin(time + " + $val + ");")の外側の括弧内は、 3 つの部分に分かれます。
    • "sy = 3 * sin(time + "
    • $val
    • ");"
    この式の sy (スケール Y) は -object フラグで指定されたコーン($name[0])のアトリビュートです。
  2. まず、$val の部分が $val = $i * 0.3; で計算された値に置き換えられます。
  3. それから、上の 3 つの部分が文字列を連結する演算子 + によって 1 つの文字列になります。 その文字列がエクスプレッションの式として、 $name[0] で表されるコーンに割り当てられます。
具体的な例として $i が 2 の場合(3 個目のコーンの場合)に、 どのように式が作られるかを見てみましょう。
  1. $val = $i * 0.3; の部分を計算し、 $val2 * 0.3 の計算結果 0.6 を代入します。
  2. expression コマンドの -string フラグ以下の ("sy = 3 * sin(time + " + $val + ");")("sy = 3 * sin(time + " + 0.6 + ");") となります。
  3. 式の 3 つの部分
    • "sy = 3 * sin(time + "
    • 0.6
    • ");"
    が + によって 1 つの文字列に連結されます。
  4. 連結された文字列が、 3 個目のコーンのエクスプレッションとして定義されます。
    sy = 3 * sin(time + 0.6 )
もし引数 $num が 10 ならば 10 個のコーンに対して、それぞれ以下のエクスプレッションが定義されます。

文字列中に変数の値を挿入

MEL では、上のエクスプレッション式のように、文字列の途中に変数値を当てはめたい事がよくあります。
そういう場合は、以下の順序で書き換えてください。

  1. 変数を、文字列中の当てはめたい位置に書いておきます。
    "sy = 3 * sin(time + $val);"
  2. 変数の左に " + を、右に + " を追加します。
    "sy = 3 * sin(time + " + $val + ");"
  3. 最後に、最初の " と、最後の " を ( ) で囲みます。
    ("sy = 3 * sin(time + " + $val + ");")

三角関数について

三角関数はエンジンのピストン運動や、波などのような往復運動をさせたい場合に良く使われます。 Maya で使用できる三角関数の種類には、sincostanasinacosatan などがありますが、 通常は sincos で十分でしょう。

三角関数には非常に多くの性質や定理がありますが、エクスプレッションで使用するときには基本的な性質だけわかっていれば良いでしょう。
たとえば、 $a * sin($b * time + $c) + $d という式があったとすると、以下のような性質があります。

練習

参考

練習課題


Prev | Next
Home | Contents
Mail