[Papervision3D] BitmapTransparentMaterial class - feedback optimisations

Justin Lawerance Mills JLM at justinfront.net
Fri Aug 8 10:45:29 PDT 2008


I created this useful material that allows setting of alpha at  
runtime on a material, please let me know if there are improvements  
you would make or alternate design decisions, note I have been using  
it in a Great White that is not current so be warned it might need an  
odd tweek to run in the latest code base, but theoretically should  
work fine.

cheers ;J

[code]
package net.justinfront.xn2carousel.helpers
{

     // please retain credits with code
     // Created JLM at Justinfront DoT net
     // August 2008

     import flash.display.BitmapData;
     import org.papervision3d.materials.BitmapMaterial;
     import flash.display.*;

     import flash.geom.*;
     import org.papervision3d.Papervision3D;
     import org.papervision3d.core.render.draw.ITriangleDrawer;


     /**
     * The BitmapTransparentMaterial class
     *	can set alpha on instances.
     */
     public class BitmapTransparentMaterial extends BitmapMaterial  
implements ITriangleDrawer
     {


         private var _mc:                *;
         private var _wrap:              Sprite;

         // stores previous set alpha so that text is not re-rendered  
unless needed.
         private var _oldAlpha:          Number;

         //quick access to BitmapData for different alphas.
         private var _precalculated:     Object = {};



         /**
         * A texture object.
         */
         override public function get texture(): Object
         {

             return this._texture;

         }


         /**
         *	sets the texture ( Do not call externally if asset is  
changed since the constructor sets a wrapper up
         */
         override public function set texture( asset:Object ):void
         {

             _mc = asset;

             // only create as many bitmaps as there are alpha levels.
             //256 is a lot of levels let rationalise the alphas to  
16 levels
             // ( 16 * 16 = 256 ), then make sure its a whole number  
and make it a string.
             var nearestAlpha 	=  'alpha' + String( int(alpha* 
(256/16)) );

             var newBitmapD  =  _precalculated[ nearestAlpha ];
             var storeCurrentBitmap: BitmapData;  	

             if( newBitmapD == undefined )
             {

                 // Copy a wrapper since copying _mc directly will  
not preserve alpha values
                 storeCurrentBitmap = copyToBitmapWithTransparency 
( _wrap );
                 bitmap   = storeCurrentBitmap;
                 _precalculated[ nearestAlpha ] = storeCurrentBitmap;
                 _texture = _precalculated[ nearestAlpha ];

             }
             else
             {

                 bitmap   = _precalculated[ nearestAlpha ];
                 _texture = _precalculated[ nearestAlpha ];

             }

             // do I need this..
             //maxU = maxV = 1;

             updateBitmap();

         }


         /**
         * Allows you to set the alpha
         */
         public function set alpha( val: Number )
         {

             if( val < 0 )
                             val = 0;
             // round to the nearest 16th reduce possible alpha.

             val = Math.round( val*16 )/16;
             _mc.alpha = val;

             if( _oldAlpha != _mc.alpha )
             {

                 texture = _mc;
                 _oldAlpha = _mc.alpha;

             }

         }


         /**
         * Allows you to get the current set alpha
         */
         public function get alpha():Number
         {

             return _mc.alpha;

         }


         /**
         *Constructor
         */
         public function BitmapTransparentMaterial 
(  mc:                 DisplayObjectContainer,
                                                      
precise:            Boolean = false ):void
         {

             wrapMc( mc );

             texture         = mc as Object;

             this.precise    = precise;
             maxU            = maxV      = 1;

         }


         /**
         * Wraps the input sprite/movie so that when alpha is applied  
it can be copied	
         */
         private function wrapMc( mc: DisplayObjectContainer ):void
         {

             mc.cacheAsBitmap    = true;
             _wrap               = new Sprite();

             _wrap.addChild(mc);
             _wrap.cacheAsBitmap = true;

         }


         /**
         *	Copies a Sprite to a BitmapData
         */		
         private function copyToBitmapWithTransparency( mc :  
Sprite ): BitmapData
         {

             var wide:       Number          = mc.width;
             var hi:         Number          = mc.height;
             var point:      Point           = new Point( 0, 0 );
             var rect:       Rectangle       = new Rectangle( 0 , 0,  
wide, hi );
             var abitmap:    BitmapData      = new BitmapData( wide,  
hi, true, 0x00000);

             abitmap.draw( mc );
             abitmap.copyPixels( abitmap, rect, point, abitmap,  
point, false );

             return abitmap	

         }

     }

}
[/code]





More information about the Papervision3D mailing list