[Flash Player 10 #1] 3D のプリミティブを回してみる。
ついにベータ版が登場した Flash Player 10 。GPU サポートやテキスト周りの強化なんかがありますが、その辺りは他の人に任せるとして…。3D が正式にサポートされたことが何とも嬉しいです。いくつか試してみたので、デモをアップしてみます。
※ 要 Flash Player 10
解説を交えたコードは下記の通り。
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Vector3D;
import flash.text.TextField;
import net.unbland.debug.FPS;
import primitives.Cube;
import primitives.Plane;
[SWF(width=320, height=320, backgroundColor=0xDDDDDD, frameRate=30)]
public class Demo01 extends Sprite
{
// 描画用のスプライト
private var canvas:Sprite = new Sprite();
// 透視投影のためのクラス
private var projection:PerspectiveProjection = new PerspectiveProjection();
// 3D シーン(ステージには配置しない)
private var scene:Sprite = new Sprite();
// 3D プリミティブ(別クラスで定義)
// 平面用
private var primitive:Plane = new Plane();
// 立方体用
//private var primitive:Cube = new Cube();
public function Demo01():void
{
// ステージの設定、3D には関係無い
setupStage();
// 3D では中心点が左上でなく、中央になるので画面中央に配置
canvas.x = canvas.y = 160;
addChild(canvas);
// プロジェクションの視野角を決める
// これにより焦点距離が変わる
projection.fieldOfView = 60;
// scene.transform.matrix3D は最初は空になっている(バグ?)ので、
// 行列を代入しておく
scene.transform.matrix3D = new Matrix3D();
// 実際に描画を行う関数を毎フレーム実行
scene.addEventListener(Event.ENTER_FRAME, renderScene);
}
private function renderScene(e:Event):void
{
// 変換用行列を作成
var world:Matrix3D = scene.transform.matrix3D.clone();
// 描画用の頂点情報が格納されたベクター
var vertices:Vector.<Number> = new Vector.<Number>();
// プロジェクションの行列を変換用行列に乗算
world.append(projection.toMatrix3D());
// プリミティブの各頂点を走査
for each (var vertex:Vector3D in primitive.vertices)
{
// 変換用行列で頂点をシーンの座標系に変換
var v:Vector3D = world.transformVector(vertex);
// プロジェクションの焦点距離を元に計算
v.w = projection.focalLength / (projection.focalLength + v.z);
// スクリーン上に投影
v.project();
// 描画用頂点に追加
vertices.push(v.x, v.y);
}
// ポリゴンを描画
canvas.graphics.clear();
canvas.graphics.beginFill(0xDDDDDD);
// 平面用
canvas.graphics.drawTriangles(vertices, primitive.indices);
// 立方体用
//canvas.graphics.drawTriangles(
//vertices, primitive.indices, null, TriangleCulling.NEGATIVE
//);
// シーンを回転
scene.rotationY += 2;
scene.rotationZ += 1;
}
private function setupStage():void
{
FPS.show(stage);
stage.showDefaultContextMenu = false;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
graphics.lineStyle(1, 0xAAAAAA);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(10, 10, 300, 300);
}
}
}
FlashDevelop の開発途中版が早くも Flash Player 10 に対応しており、Vector とかのコードヒントとかもで出るのでオススメです。twitter での beinteractive 先生のコメントで知ったのですが、Flash Player 10 Debug 版もこっそりあるみたいなので合わせて使えばウハウハです。今回のサンプルに使ったプロジェクト(プリミティブ含む)を上げておきますので、参考にどうぞ。
[FLASH10]drawRectanglesでパノラマ画像をテクスチャリング
円環状の多面体(長方形が複数繋がったようなやつ。各長方形は三角形二つで構成)に沿ってパノラマ画像を貼付け。胆はテクスチャ貼付け用のUVT座標の設定と、円環…