Flash Player 10 meets 3D

about 1 year ago malczak actionscript graphics comments

It have been over one month since last post, but there were so many things that needed to be done :) In this post i will just drop a line about 3d in new Flash Player 10. Recently Im writing some experiments, tring to understand how 3d in fp10 works. Doing this I also came across one very interesting site - http://wonderfl.kayac.com. At this page You can write and build Your AS3 code. But lets get back to 3d...
Writing 3d 'worlds' using flash drawing API is hard, because 3d philosophy is a bit twisted. This post shows how to manage multiple sprites in a 3d as3 world. You will see how to create 3d spiral, that can be used as an image gallery. To create 3d spiral from a set of DisplayObject's we need to perform these steps :

  • place objects on a circle in XZ plane
  • add some shift in Y direction
  • append some additional rotation (just to look better)

There is also one important step that need to be done. Flash Player doesn't do any Z sorting of DisplayObjects. Drawing order is based on objects depth (child index) not on its Z coordinate. This is how it works.

Flash player (ver. 10.0.0) is required to see this content. Please update to newest possible version.

Get newest Adobe Flash player

And here is code (check out woderfl to modify online) with few comments:
package {
 import flash.display.*;
 import flash.geom.*;
 import flash.filters.*;
 import flash.events.Event;

 [SWF(width="400", height="400", backgroundColor="0xffffff", frameRate="15")]    
  
  /**
  * @author : Mateusz Malczak (http://segfaultlabs.com)
  */
  public class Main extends MovieClip {

     private var bv:Vector. = new Vector.(0,false);
     private var stepRotMtx : Matrix3D;

     public function Main():void
     {
/* You can use images instead of this */
        var s:BitmapData = new BitmapData(120,120);
        s.perlinNoise(200,200,8,Math.random(),true,true,BitmapDataChannel.BLUE,true);
        
        var blurf:BlurFilter = new BlurFilter(8,0);    

/*constants*/
        var R:Number = 200; /* spiral radius */
        var sd:Number = 18; /* spiral leap */

        var rdl:Number = R * Math.sqrt( 2*(1 - Math.cos( 36*Math.PI/180 ) ) );
        rdl = Math.atan2( rdl, sd ) *180/Math.PI; /* side radius beetween two elements */
        
        /* create bitmaps */
        var i:uint;
        var b:Bitmap;
        var m3d:Matrix3D;
        var alfa:Number;
            for ( i=0; i<40; i+=1 )
            {
                b = new Bitmap(s);
                m3d = new Matrix3D();
/* place objects on a circle in XZ plane and add Y shift */
                m3d.appendTranslation(-60,-60,0);
                m3d.appendRotation( rdl, Vector3D.Z_AXIS );
                m3d.appendRotation( -5, Vector3D.X_AXIS );
                m3d.appendRotation( (90-36*i), Vector3D.Y_AXIS );
                alfa = 36*i*Math.PI/180;
                m3d.appendTranslation( R*Math.cos(alfa), 
                                       sd*i, 
                                       R*Math.sin(alfa) );
/* move to the center on stage */
                m3d.appendTranslation( 200, 0, 150 );
                m3d.appendRotation( 25, Vector3D.X_AXIS );

                b.transform.matrix3D = m3d;
                b.filters = [ blurf, 
                              new ColorMatrixFilter(           
                                [
                                        1,0,0,0,5*i,
                                        0,1,0,0,2*i,
                                        0,0,1,0,-2*i,
                                        0,0,0,1,0
                                ] )
                            ];
                bv.push( b );    
                addChild( b );
            }; 
/* enter frame rotation modification, each EF is a 10 degree in OY rotation */
       stepRotMtx = m3d = new Matrix3D();
       m3d.appendRotation( -25, Vector3D.X_AXIS );
       m3d.appendTranslation( -200, 0, -150 );
       m3d.appendRotation( 10, Vector3D.Y_AXIS );
       m3d.appendTranslation( 200, 0, 150 );
       m3d.appendRotation( 25, Vector3D.X_AXIS );

       addEventListener( Event.ENTER_FRAME, ef );
     }

    public function ef( evt:Event ):void
    {
        var b:Bitmap;
        var m3d:Matrix3D;
            for each ( b in bv )
                b.transform.matrix3D.append( stepRotMtx );
/* fix z ordering, flash is not doing this with DisplayObjects */
        sortZ(); 
    }

    private function sortZ():void
    {
 /* sort on z */
        bv.sort( sortF );
/* indices fix based on depth */
        bv.forEach( reorder );
    };
    
    private function reorder( b1:Bitmap, idx:int, v:Object ):void
    {
        setChildIndex( b1, idx );
    };

    private function sortF( b1:Bitmap, b2:Bitmap ):Number 
    {    
        if ( b1.z < b2.z ) return 1;
        if ( b1.z > b2.z ) return -1;
        return 0;
    };

  }
}
Share |

Comments

No comments as yet. Be first to comment.

New comment

  1. (never shown, just for us for possible contact)

  2. (with http or https prefix)

  3. (use [code][/code] tags to post a code snippet)

  4. (javascript is required)

Website content premeditately commited by segfaultlabs (malczak & sobstel).
Layout by mlando. Icons by DryIcons.com. All rights reserved, of course.