3D オブジェクトの ViewportLayerにアクセスする
Papervison3D では 3D オブジェクトを Sprite の派生クラスである ViewportLayer に描画しています。ViewportLayer にアクセスすることで、マウスイベントを拾ったり描画された内容にフィルターをかけたりといった Sprite が持っている機能を利用できます。(Papervision3D 逆引きシリーズ)
ViewportLayer にアクセスするには
ViewportLayer にアクセスするには BasicView のプロパティである viewport(Viewport3Dのオブジェクト) の getChildLayer() メソッドを使用します。引数に DisplayObject3D のオブジェクトを渡すとそのオブジェクトの描画先である ViewportLayer を取得できます。
BasecView と Viewport3D と ViewportLayer の関係
View も Viewport3D も ViewportLayer もすべて Sprite を派生したクラスです。3つのクラスはディスプレイツリーで以下のような親子関係にあります。
- BasecView
- Viewport3D
- ViewportLayer
- ViewportLayer
- ...
- Viewport3D
- BasicView
- Camera, Scene, Viewport など 3D の描画に必須のクラスをまとめたクラス。ただし BasicView は 3D 描画に絶対必要というわけではなく、描画必須クラスをまとめるヘルパクラス的意味合いが強い。Sprite を派生しているのは 便宜上であり、BasicView を用いずに描画必須クラスを直接構築し手動でプロパティを設定したあと Viewport3D を、ドキュメントクラスに追加しても 3D は表示される。
- Viewport3D
- 3D オブジェクトを描画するスクリーンのような位置づけ。カメラと対応してそのカメラから見た 3D オブジェクトが描画される。
- ViewportLayer
- Viewport3Dに描画される個々のオブジェクトに対応するSprite。ドキュメントを読んだ限りでは getChildLayer() した時に生成されることもあるらしい。getChildLayer() されるまではすべての 3D オブジェクトが Viewport3D に描画されているが、各々の 3D オブジェクトに対応した Sprite が必要な時には ViewportLayer が生成され、描画先がこっちに変わるのかもしれない。
ソース
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.GlowFilter; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.materials.shadematerials.GouraudMaterial; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.view.BasicView; import org.papervision3d.view.layer.ViewportLayer; import org.papervision3d.lights.PointLight3D; [SWF(width="320", height="240", backgroundColor="#FFFFFF")] public class Sample004 extends Sprite { public function Sample004 () { // PaperVision のビューを作成 var view:BasicView = new BasicView(); view.camera.y = 100; view.camera.x = 300; addChild(view); view.startRendering(); // 光源を作る var light:PointLight3D = new PointLight3D(false); light.x = 500; light.y = 800; light.z = 0; // バウンドエリアに対応する 3D オブジェクトを作る var cubes:Array = []; for(var i:int=0; i<3; i++) { cubes[i] = new Cube(new MaterialsList({all:new GouraudMaterial(light, 0xeeeeee, 0x666666)}), 100, 100, 100); cubes[i].x = -150 + i*150; view.scene.addChild(cubes[i]); } // 毎フレームの処理 var cnt:int=0; addEventListener(Event.ENTER_FRAME, function(e:Event):void { view.camera.x = 800*Math.cos(cnt*Math.PI/180); view.camera.z = 800*Math.sin(cnt*Math.PI/180); cnt++; }); // 各 3DObject の ViewportLayer にアクセス for(i=0; i<3; i++) { // ViewportLayer を取得 var layer:ViewportLayer = view.viewport.getChildLayer(cubes[i]); // イベントリスナーを追加 layer.addEventListener(MouseEvent.MOUSE_OVER, function(e:MouseEvent):void { ViewportLayer(e.target).buttonMode = true; ViewportLayer(e.target).filters = [ new GlowFilter(0xcc0000) ]; }); layer.addEventListener(MouseEvent.MOUSE_OUT, function(e:MouseEvent):void { ViewportLayer(e.target).filters = []; }); } } } }