ActionScript 3.0で始めるオブジェクト指向スクリプティング

第35回 Matrix3Dクラスによる座標変換

この記事を読むのに必要な時間:およそ 3.5 分

3次元空間における(平行)移動や回転および伸縮は,Matrix3Dクラスを使って行うこともできる。Matrixというのは,数学の行列を意味する(あの映画のことではない)。3次元座標を変換するために,内部的に行列による演算が行われるためにこの呼び名がつけられた。もっとも,基本的な処理であれば,私たちがその計算を行う必要はない。座標変換の性質と特徴を知っておけば足りる※1)。

※1
実は,多くのフィルタも内部的に行列演算を行っている。もちろん,3次元は関わりなく,変換の計算をしているのは画像のピクセルごとのカラー情報だ。しかし,ユーザーは内部的な処理まで知る必要はない。どのパラメータを動かせば,どういう結果になるのかさえ捉えられればよい。Matrix3Dクラスについても同じである。

DisplayObjectインスタンスのもつMatrix3Dオブジェクトを操作する

DisplayObjectインスタンスの3次元空間における座標変換の情報をもつMatrix3Dオブジェクトは,PerspectiveProjectionオブジェクトと同じくTransformクラスのプロパティで,Transform.matrix3Dから得る。そして,Transformオブジェクトの参照は,DisplayObject.transformプロパティがもっていた第33回図6再掲)。

第33回図6 プロパティDisplayObject.transformからTransform.perspectiveProjectionの参照を得る(再掲)

第33回図6 プロパティDisplayObject.transformからTransform.perspectiveProjectionの参照を得る(再掲)

DisplayObjectインスタンスに平行移動や回転あるいは伸縮の変換を加えるには,Matrix3Dオブジェクトに対してそれぞれMatrix3D.prependTranslation(), Matrix3D.prependRotation(), Matrix3D.prependScale()といったメソッドが用いられる。なお,各メソッドの頭についているprependという語の意味は後で説明する。

Matrix3Dオブジェクト.prependTranslation(移動x座標値, 移動y座標値, 移動z座標値)
Matrix3Dオブジェクト.prependRotation(回転度数値, 回転軸)
Matrix3Dオブジェクト.prependScale(水平伸縮率, 垂直伸縮率, 奥行き伸縮率)

それでは,タイムラインに置いたMovieClipインスタンスmy_mcを,y軸で水平に45度回転してみよう。Matrix3D.prependRotation()メソッドの第1引数には,回転する角度を度数で渡す。そして,第2引数の回転軸は,Vector3Dクラスの3つの定数Vector3D.X_AXIS, Vector3D.Y_AXIS, Vector3D.Z_AXISから指定する。

// タイムライン: メイン
// タイムラインにMovieClipインスタンスmy_mcを配置
var myMatrix3D:Matrix3D = my_mc.transform.matrix3D;
myMatrix3D.prependRotation(45, Vector3D.Y_AXIS);

ところが,このフレームアクションを[ムービープレビュー]で試すと,以下のようなランタイムエラー#1009が示される。これは「オブジェクトを参照してプロパティにアクセスしようとしているステートメントで,実際にはオブジェクトが存在しない場合に起こる」エラーだった(第22回「MovieClipシンボルにクラスを定義する」フレームアクションをクラスに移行する」)。

TypeError: Error #1009: nullのオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。

実際,MovieClipインスタンスのDisplayObject.transformプロパティから取出したTransform.matrix3Dプロパティの値をtrace()関数で[出力]すると,nullが示される図1)。なぜなら,タイムラインのインスタンスすべてに3次元座標の操作を加える必要はない。そして,インスタンスに3次元空間の情報をもたせれば,少なからず負荷が増える。そのため,DisplayObjectインスタンスは,デフォルトではMatrix3Dオブジェクトをもたないのである。

図1 MovieClipインスタンスのDisplayObject.transform.matrix3Dプロパティはnull

図1 MovieClipインスタンスのDisplayObject.transform.matrix3Dプロパティはnull

DisplayObjectインスタンスにMatrix3Dオブジェクトを与えるには,何かしら3次元座標空間の操作を加えればよい。スクリプトであれば,簡単なのはDisplayObject.zプロパティに0を設定する。z座標値はデフォルトが0なので,見た目は変わりない。しかし,3次元空間の操作が行われたことにより,インスタンスのDisplayObject.transformプロパティのもつTransform.matrix3DプロパティにMatrix3Dオブジェクトが生成される。

// タイムライン: メイン
// タイムラインにMovieClipインスタンスmy_mcを配置
my_mc.z = 0;   // z座標を操作
var myMatrix3D:Matrix3D = my_mc.transform.matrix3D;
trace(myMatrix3D);   // 出力: [object Matrix3D]
myMatrix3D.prependRotation(45, Vector3D.Y_AXIS);

これで,インスタンスのMatrix3Dオブジェクトをメソッドで操作して,座標が変換できる。Matrix3D.prependRotation()メソッドにより,MovieClipインスタンスはy軸で水平に45度回転する図2)。なお,回転は軸の正の方向に対して,右ネジを回す向きが正の角度になる。

図2 z座標を設定するとMatrix3Dオブジェクトが生成されて3次元空間の操作は可能になる

図2 z座標を設定するとMatrix3Dオブジェクトが生成されて3次元空間の操作は可能になる

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入