Papervision3Dで背景抜きFLV再生

Papervision3DのVideoStreamMaterialでFLV(AfterEffectsで背景抜きしたFLV)を再生させようと思ったら、
素直に背景が透明な状態で表示してくれなかったのでメモ。(2008/5/15 17:13 現在の最新リビジョン557)

実際の表示結果としては、背景部分がVideoStreamMaterial.fillColorで塗り潰されてしまう。


VideoStreamMaterialでは、生成したVideoオブジェクトを絶えずBitmapDataにdrawする事で、あたかも3D空間内で動画が再生されているように表現している。
ここで、

VideoStreamMaterial.as(一部抜粋)

public override function updateBitmap ():void
{
    try
    {
        // copies the scale properties of the video
        var myMatrix:Matrix = new Matrix();
        myMatrix.scale( this.video.scaleX, this.video.scaleY );
        
        // Fills the rectangle with a background color
        this.bitmap.fillRect ( this.bitmap.rect, this.fillColor );
        
        // Due to security reasons the BitmapData cannot access RTMP content like a NetStream using a FMS server.
        // The next three lines are a simple but effective workaround to get pass Flash its security sandbox.
        //this.video.attachNetStream ( null );
        this.bitmap.draw( this.video, myMatrix, this.video.transform.colorTransform );
        this.video.attachNetStream ( this.stream );
    }catch(e:Error)
    {
        //
        trace(e);
    }
}

このdrawしてる部分。
自身のプロパティとしてBitmapDataを保持している。
では、このBitmapDataはいつ生成されているのか。

それは、継承元のMovieMaterialの下記の部分
(createBitmapFromSpriteメソッドでもbitmapをセットしていますが、今回問題になった処理ではないので。)

MovieMaterial.as(一部抜粋)

protected function initBitmap( asset:DisplayObject ):void
{
    // Cleanup previous bitmap if needed
    if( bitmap )
        bitmap.dispose();
    
    // Create new bitmap
    bitmap = new BitmapData( asset.width, asset.height, this.movieTransparent );
}

ここで、「this.movieTransparent」。
これがtrueに設定されていないと、当たり前のように透明にはなりませんよねー。
じゃぁ、VideoStreamMaterialで、どのタイミングで設定できるのか?

設定するとなると、皆様はきっと下記のようにしますよね。
少なくとも、berianはそうしたくなります。

var videoStreamMaterial:VideoStreamMaterial = new VideoStreamMaterial(video, stream);
videoStreamMaterial.movieTransparent = true;

だがしかし!!
だがしかしなのですYO!!

隊長!!
VideoStreamMaterialのインスタンスが生成された時点で、bitmapプロパティは作成済みであります!!


現状のVideoStreamMaterialでは、外から設定出来るタイミングが・・ありません。。。
残念だ・・。。
本当に残念だ・・。。


なので、VideoStreamMaterialのコンストラクタ引数に「transparent」を追加して、
「super」の引数にそれを追加してあげました。

以下、修正したVideoStreamMaterialコンストラクタ。

VideoStreamMaterial.as(一部抜粋)

public function VideoStreamMaterial ( video:Video, stream:NetStream, transparent:Boolean = false )
{
    // store the values
    this.stream = stream;
    this.video = video;
    animated = true;
    
    // init the material with a listener for the NS object 
    initMaterial ( video, stream );
    
    /**
     * 実は、super(MovieMaterialコンストラクタ)の引数にはtransparentがあります。。
     * 
     * public function MovieMaterial( movieAsset:DiplayObject=null, transparent:Boolean=false, animated:Boolean=false )
     * {
     *
     *
     *
     * }
     */
    super ( DisplayObject(video), transparent );
}

これで背景抜きFLVが、めでたく表示されました。


本来はこうあるべきですよね!?
透過させると、何か他の問題が出てくるのかな??(もちろん負荷的な事以外に)
まぁ、もっと良い方法があれば、それに越した事はありませんが、とりあえずこれでw

でも、GreatWhiteでもこの部分は、今のところ(リビジョン557)特に変更ないしなー・・
とりあえず、試しにissueしとこうかな。