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

第46回 分割した三角形にビットマップを変形して塗る

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

前回は,Graphics.drawTriangles()メソッドにより,三角形に分けた領域をビットマップで塗った。今回は,このいわゆる「テクスチャマッピング」について,さらに解説を加える。このメソッドの使い方は奥深い。その練習も兼ねよう。

矩形のビットマップを任意の四角形に変形する

まずは,前回のおさらいから入る。Graphics.drawTriangles()メソッドを使えば,正方形のビットマップも自由な四角形に変形できる。たとえば,100×100ピクセルのビットマップを,以下のような四角形に塗るとしよう。なお,位置合わせがしやすいように,Shapeインスタンスはステージの真ん中におく。したがって,基準点(0, 0)は中央になる。各頂点には,わかりやすいように整数の頂点番号(0~3)を添えた。

図1 正方形のビットマップを自由な四角形に変形する

図1 正方形のビットマップを自由な四角形に変形する

Graphics.drawTriangles()メソッドは,第1引数のVectorオブジェクト(Numberベース型)で三角形の頂点座標を順に納め,第3引数のVectorオブジェクト(Numberベース型)にはビットマップの対応するuv座標を定めて渡した。フレームアクションは,つぎのスクリプト1のようになるだろう。

Graphicsオブジェクト.drawTriangles(頂点座標, null, uv座標) 

スクリプト1 三角形分割した領域にビットマップを変形して塗る

// フレームアクション
var nCenterX:Number = stage.stageWidth / 2;
var nCenterY:Number = stage.stageHeight / 2;
var myShape:Shape = new Shape();
var myGraphics:Graphics = myShape.graphics;
var myTexture:BitmapData = new Image();
var vertices:Vector.<Number> = new Vector.<Number>();
var uvData:Vector.<Number> = new Vector.<Number>();
myShape.x = nCenterX;
myShape.y = nCenterY;
vertices.push(-50, -50);   // 頂点0
vertices.push(50, -70);   // 頂点1
vertices.push(-70, 70);   // 頂点2
vertices.push(50, -70);   // 頂点1 (重複)
vertices.push(70, 50);   // 頂点3
vertices.push(-70, 70);   // 頂点2 (重複)
uvData.push(0, 0);
uvData.push(1, 0);
uvData.push(0, 1);
uvData.push(1, 0);   // 重複
uvData.push(1, 1);
uvData.push(0, 1);   // 重複
myGraphics.beginBitmapFill(myTexture);
myGraphics.drawTriangles(vertices, null, uvData);
myGraphics.endFill();
addChild(myShape);

[ムービープレビュー]を確かめると,指定した四角形にビットマップが変形して塗られる図2)⁠結果はまったく問題ない。しかし,スクリプト1を見ると,四角形の頂点は4つなのに,Graphics.drawTriangles()メソッドに渡した第1引数と第3引数のVectorオブジェクト(頂点座標とuv座標)にはそれぞれ6組,つまり12の数値エレメントが加えられている。ふたつの三角形に頂点1と2が重複しているからだ(前掲図1参照)⁠

図2 指定した四角形にビットマップが変形して塗られた

図2 指定した四角形にビットマップが変形して塗られた

テクスチャマッピングは,面を細かな三角形に分けてビットマップを貼っていく手法である。三角形の数が多くなると,頂点の重複もそれに伴って増えてしまう。Graphics.drawTriangles()メソッドの第2引数を使えば,座標の重複は避けることができる。

三角形の頂点の組を定める - Graphics.drawTriangles()メソッドの第2引数

前掲スクリプト1Graphics.drawTriangles()メソッドに渡す引数の指定を変えよう。第1引数(vertices)の頂点座標は,重複しない4組つまり8つの数値エレメントのみVectorオブジェクトに加える。対応する第3引数(uvData)のVectorオブジェクトも,同じく8つの数値エレメントを納めることになる。しかし,これではどの3頂点で三角形をつくるのかがわからない。その3頂点の組合わせを決めるのが第2引数だ。

Graphics.drawTriangles()メソッドの第2引数はintベース型のVectorオブジェクトで,三角形の3頂点番号の組を納める。頂点番号は0から始まる整数で,第1引数に納めた座標の順序にしたがう。3頂点番号がひと組になるので,スクリプト1の例なら三角形ふたつで,6つの整数を加えればよい。その手直しをしたのが,つぎのスクリプト2だ。

スクリプト2 Graphics.drawTriangles()メソッドに第2引数の頂点番号の組を渡す

// フレームアクション
var nCenterX:Number = stage.stageWidth / 2;
var nCenterY:Number = stage.stageHeight / 2;
var myShape:Shape = new Shape();
var myGraphics:Graphics = myShape.graphics;
var myTexture:BitmapData = new Image();
var vertices:Vector.<Number> = new Vector.<Number>();
var indices:Vector.<int> = new Vector.<int>();
var uvData:Vector.<Number> = new Vector.<Number>();
myShape.x = nCenterX;
myShape.y = nCenterY;
// 頂点座標
vertices.push(-50, -50);   // 頂点0
vertices.push(50, -70);   // 頂点1
vertices.push(-70, 70);   // 頂点2
vertices.push(70, 50);   // 頂点3
// 頂点番号
indices.push(0, 1, 2);   // 左上三角形
indices.push(1, 3, 2);   // 右下三角形
// uv座標
uvData.push(0, 0);
uvData.push(1, 0);
uvData.push(0, 1);
uvData.push(1, 1);
myGraphics.beginBitmapFill(myTexture);
myGraphics.drawTriangles(vertices, indices, uvData);
myGraphics.endFill();
addChild(myShape);

Graphics.drawTriangles()メソッドに渡す第1引数のVectorオブジェクト(Numberベース型)には,重複のない4頂点の座標を納めた。その順序は前掲図1の頂点番号に合わせている。第3引数のVectorオブジェクト(Numberベース型)にも,もちろん第1引数に対応するuv座標を4組加えた。

そして,第2引数のintベース型Vectorオブジェクト(indices)には,ふたつの三角形の3頂点番号の組を定めた。3頂点番号の順序は,今のところ気にしなくとも構わない。ただ,後のちのため,本連載では時計回りに決める※1)⁠

[ムービープレビュー]を確かめると,描かれるビットマップは前掲スクリプト1と変わらない(前掲図2)⁠しかし,座標の数が減ると,内部的な負荷は軽くなる※2)⁠また,座標と三角形の指定を分けることで,スクリプトも扱いやすくなる。

※1
3頂点の順序を時計回りか半時計回りかに決めておくと,後の回で解説する面の裏表が調べられる。
※2
[ヘルプ]の[Graphics]クラスでdrawTriangles()メソッドの項を見ると,第2引数の「インデックスを使用すると,通常,送信されるデータ量と計算されるデータ量が減少」すると説明されている。

著者プロフィール

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

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

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入