![]()
Papervision3D の平面に外部 swf をロード
寺井です。Papervision3D のバージョン 2.0:別名「GreatWhite」を触ってみました。
表題にもあるように、今回は「外部 swf ファイルをロードして、Papervision3D の平面(Plane)上に貼り付ける。」というお題です。
3Dオブジェクトの面に対してムービーを貼り付ける「MovieMaterial」の挙動で少し苦労したのでした。
MovieMaterial の使い方は以下のようになります。
new MovieMaterial(
movieAsset:DisplayObject=null,
transparent:Boolean=false,
animated:Boolean=false,
precise:Boolean = false
);
引数はそれぞれ:
- movieAsset: テクスチャとして貼り付けたい DisplayObject(僕のサンプルでは Sprite 型の exStageSpr)
- transparent: 透過するかどうか。
true, false どっちにしても外部 swf の背景は反映されない。何が透過されるんだろう?今回は研究外。
追記:この transparent パラメーターについて note.x 様が丁寧&カッコイイサンプルで解説をしてくださっています。
「note.x | [PV3D2.0] materials.MovieMaterial」 - animated: アニメーションさせるかどうか。今回はロードした swf を再生させたいので true に設定。
- precise: Render the bitmap using linear texturing を設定できる。
ということで、第1引数に Sprite インスタンス「exStageSpr(名前は任意)」を渡す。その exStageSpr に外部 swf をロードした loader インスタンスを addChild するという、常識的なアプローチ。
結果からいうと、ロードするスプライト上で、事前に drawRect してロード対象の外部 swf ムービーと同じサイズの矩形を描画しておかないとダメ!!っぽい。空スプライトに loader を addChild していた場合には何も表示されなくてハマりました。
ソースはこんな感じ。Main.as としてドキュメントクラスに設定してください。
/* 同じディレクトリに"external.swf"というSWFファイルがあり、これをロードしてPV3D平面に貼り付けるテスト。 回転を止めたければ handleEnterFrame とかは不要。回転を直接指定してください。 40行目のコメントがミソ 「miscellaneous [ActionScript 3.0] PaperVision3D 2.0 GreatWhite」 (http://yamasv.blog92.fc2.com/blog-entry-101.html) 様のエントリをベースに作成させていただきました。 */ package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.display.Loader; import flash.net.URLRequest; import org.papervision3d.cameras.FreeCamera3D; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.MovieMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; public class Main extends Sprite { private var renderer:BasicRenderEngine private var scene:Scene3D; private var camera:FreeCamera3D; private var viewport:Viewport3D; private var pointLight:PointLight3D; public function Main() { //テクスチャ用ムービークリップ。 var exStageSpr:Sprite = new Sprite(); //外部アセットをロードする前に予め矩形描画等でエリア確保が必要っぽい!! //読み込むムービーの背景色と同じ塗りの色にする exStageSpr.graphics.beginFill(0xFF3300); //読み込むムービーのムービーサイズに合わせる exStageSpr.graphics.drawRect(0, 0, 300, 200); exStageSpr.graphics.endFill(); var loader:Loader = new Loader(); exStageSpr.addChild(loader); loader.contentLoaderInfo.addEventListener(Event.INIT, initListener); loader.load(new URLRequest("external.swf")); renderer = new BasicRenderEngine(); scene = new Scene3D(); camera = new FreeCamera3D(); viewport = new Viewport3D(0, 0, true, false); addChild(viewport); //カメラ設定は外部素材のサイズに応じて調整してください。 camera.z = -400; camera.focus = 100; camera.zoom = 2; //exStageSprをテクスチャに設定する。 var movieMat:MovieMaterial = new MovieMaterial(exStageSpr, false, true, false); movieMat.doubleSided = true; //裏表表示 //平面を作成 var plane:Plane = new Plane(movieMat,300,200,5,5); scene.addChild(plane); stage.addEventListener(Event.ENTER_FRAME, handleEnterFrame); } private function initListener(e:Event):void { trace("外部 SWF ロード完了") } private function handleEnterFrame(e:Event):void { //カメラ設定は外部素材のサイズに応じて調整してください。 camera.x=camera.y=camera.z=0; camera.yaw(1); camera.moveBackward(200); renderer.renderScene(scene, camera, viewport); } } }
ちなみに本体ムービーは AS3 で、外部 swf は AS2 なのですが、ただ再生させるぐらいなら動くんですね。
