r = new Random(0); for (i = 0; i < 100; i++) { sphere = new Sphere(0.05, 0.05, 0.05); pos = new Vec3(r.nextDouble(), r.nextDouble(), r.nextDouble()); script.addObject(sphere, new CoordinateSystem(pos, 0, 0, 0)); }
これだけで、以下の図のような「球の雲」ができます。
この「雲」をシーン内でドラッグしてみると、ほかのオブジェクトと同じように振る舞うのが分かります。移動・回転ができ、テクスチャや材質を割り当てられます。三角メッシュへの変換もできます。
オブジェクトメニューから「編集...」を選択すると、このスクリプトが表示されます。スクリプトはいつでも変更でき、オブジェクトはそれに応じて変化します。
もう少し注意してこのスクリプトを見て、各行で何をしているのか実際に見てみましょう。ここでは球をランダムに配置したいので、最初の行で乱数を発生させます。
r = new Random(0);
乱数発生の根を0として初期化することに注意してください。すべての球がいつも同じ場所に配置されることを保証するためには、ここが重要です。こうしなければ、レンダーごとに球それぞれが違う場所に移動してしまいます。
I Beanshell でプログラミングをしたことがなければ、この行でいくつかおかしく見える部分に気づくでしょう。まず変数 r の出どころです。私は宣言しませんでした。インタープリタ(機械語への翻訳機能)はどうやってこの変数のタイプを見分けるのでしょう。
Beanshell は ダイナミックタイピング をサポートしています。これは(ほかのものとの中で)宣言なしで変数を扱えることを意味します。変数は "loosely typed"(弱く型付けされたもの)となり、どのタイプのどの値でも割り当てることができます。タイプのチェックは実際に変数を使ったときに行われます。ある変数が割り当てられたオブジェクトについて、存在しないメソッドを呼び出そうとすると、エラーメッセージを受け取ることになります。お望みでなければダイナミックタイピングは使う必要がありません。Java で行うように、変数の宣言を正確に行うこともできます。しかしこのような短いスクリプトを書く場合、ダイナミックタイピングは非常に便利です。
次に、記述者が実際に "java.util.Random" の意図で「乱数」と言ったとき、スクリプトがそれを知る方法です。そのパッケージはインポートされていません。この疑問の答えは意外と簡単です。便利のため、すべてのスクリプトに以下のパッケージが自動でインポートされます。
次に、スクリプトには100回実行するループがあり、ループするごとに球を作成します。これは以下のコマンドで行います。
sphere = new Sphere(0.05, 0.05, 0.05);
球は Art of Illusion で定義されたオブジェクトの、多くのクラスの1つです。このコンストラクタには X 半径・Y 半径・Z 半径の3つの項があり、(その名前とは異なり)実際は一般的な楕円を表現します。今回は3つすべてを同じ値に設定しているので、球になります。
次に X, Y, Z 座標をランダムに選んで、球の位置を選択します。
pos = new Vec3(r.nextDouble(), r.nextDouble(), r.nextDouble());
最後に、スクリプト形状に球を追加します。
script.addObject(sphere, new CoordinateSystem(pos, 0, 0, 0));
"script" 変数は artofillusion.script.ScriptedObjectController クラスのオブジェクトを参照します。この変数は、シーンで操作をやりとりしたりスクリプト形状の要素を作り出す、このオブジェクトを通して使われます。今回の場合、addObject() メソッドを呼び出しました。このメソッドは、追加するオブジェクトと、そのオブジェクトの位置と向きを定義する座標(artofillusion.math.CoordinateSystem)の2つの項を含みます 。
座標系のコンストラクタは位置(座標の基点)と3つの回転軸の角度を取ります。これは、別の方法で向きを指定できるほかのコンストラクタを持ちます。座標系は常に、スクリプト形状自体の座標系に関連して補間されることに注意してください。このためオブジェクト全体として、シーン内で移動や回転ができます。
この例でご覧のように、スクリプト形状はまさに、ほかのオブジェクトの「集合」です。今回のスクリプトでは100個の球を作成しました。しかしほとんどの用途では、スクリプト形状はそれでも単一のオブジェクトと考えましょう。今回の例の球はシーンに1個ずつ追加されたものではありません。個別には選択できず、また、スクリプトを球ではなく立方体の作成に変更すると、球は即座に消え、立方体に置き換わります。