In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

octo2sphere

catmull-clark transformation
Get Adobe Flash player
by malczak 10 Jan 2009

    Tags

    3D
    Embed
/* catmull-clark transformation */
package {
 import flash.display.*;
 import flash.geom.*;
 import flash.filters.*;
 import flash.events.*;
 import flash.utils.*;
 import flash.text.*;

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

     private var m3d : Matrix3D;
     private var s : BitmapData;
     private var R :Number;
     private var t :Timer;
     private var tf : TextField;

     private var vs:Vector.<Number> = new Vector.<Number>(0,false);
     private var vsp:Vector.<Number> = new Vector.<Number>(0,false);
     private var fs:Vector.<int> = new Vector.<int>(0,false);
     private var uvt:Vector.<Number> = new Vector.<Number>(0,false);

     public function sphere():void
     {
        s = new BitmapData(320,320);
        var tmp0:BitmapData = new BitmapData(320,320);
        s.perlinNoise(320,320,8,Math.random(),true,true,BitmapDataChannel.BLUE,false);
        tmp0.perlinNoise(320,320,8,Math.random(),true,true,BitmapDataChannel.GREEN,false);	
	s.draw( tmp0, null, null, BlendMode.ADD );
        tmp0.perlinNoise(320,320,8,Math.random(),true,true,BitmapDataChannel.BLUE,false);
	s.draw( tmp0, null, null, BlendMode.ADD );
        tmp0.perlinNoise(320,320,8,Math.random(),true,true,BitmapDataChannel.ALPHA,false);
	s.draw( tmp0, null, null, BlendMode.ADD );
	tmp0.dispose();

        R = 160; /* sphere radius */
        var pi4:Number = Math.PI*0.25;
        var pi2:Number = 90 * Math.PI / 180;
        /* octohedra vertices */
         vs.push(  0, -R, 0 );
         vs.push( R * Math.sin(pi4),0, R* Math.cos(pi4) );
         pi4 += pi2;
         vs.push( R * Math.sin(pi4),0, R* Math.cos(pi4) );
         pi4 += pi2;
         vs.push( R * Math.sin(pi4),0, R* Math.cos(pi4) );
         pi4 += pi2;        
         vs.push( R * Math.sin(pi4),0, R* Math.cos(pi4) );
         pi4 = Math.PI*0.25;        
         /* one vertex extra to get proper bitmap textring */
         vs.push( R * Math.sin(pi4),0, R* Math.cos(pi4) );
         vs.push( 0, R, 0 );
        /* faces */
         fs.push( 0,1,2 );    
         fs.push( 0,2,3 );    
         fs.push( 0,3,4 );
         fs.push( 0,4,5 );
         fs.push( 0,1,5 );
         fs.push( 6,2,1 );
         fs.push( 6,3,2 );
         fs.push( 6,4,3 );
         fs.push( 6,5,4 );
         fs.push( 6,1,5 );
         /* texturing */ 
           uvt.push( 0.5  ,0  , 0 );
            uvt.push( 0   ,0.5, 0 );
            uvt.push( 0.25,0.5, 0 );
            uvt.push( 0.50,0.5, 0 );
            uvt.push( 0.75,0.5, 0 );
            uvt.push( 1   ,0.5, 0 );
           uvt.push( 0.5  ,1  , 0 );
        
         vsp.length = vs.length/3*2;
         m3d = new Matrix3D();
         m3d.appendRotation(30,Vector3D.Y_AXIS );
         m3d.appendRotation(30,Vector3D.X_AXIS );
         m3d.appendTranslation( 200, 200, 300 );        
	 var pp:PerspectiveProjection = transform.perspectiveProjection;
	 pp.fieldOfView = 60;
	 pp.focalLength = 200;
	 pp.projectionCenter = new Point(200,200);
	 transform.perspectiveProjection = pp;
	       
         addEventListener( Event.ENTER_FRAME, ef );

         t = new Timer(5000,5);
         t.addEventListener( TimerEvent.TIMER, subdivide );
         t.start();	

	 draw();              
  
         tf = new TextField(); 
         tf.autoSize = "left";                   
         tf.text = "octahedra transformed into sphere\nvertices : "+vs.length/3;
         addChild(tf);
     }

    /**
    * catmull-clark division, without duplicating edge division
    */
    public function subdivide( evt:Event ):void
    {
	var cnt:int = fs.length;
	var i:int, j:int, k:int, n:int;
        var i3:int, j3:int, k3:int;
        var n1:int, n2:int, n3:int;
	var v:Vector3D = new Vector3D();
        var done:Object = {};
	n = vs.length/3;
        var e:String = "";
		while ( cnt>0 )
		{	
			i = fs.shift(); j = fs.shift(); k = fs.shift();                        
                        i3 = i*3; j3 = j*3; k3 = k*3;
                        e = Math.max(i,j)+""+Math.min(i,j);
                            if ( done[e]==null )
                            {
        			v.x = 0.5*(vs[i3  ] + vs[j3  ]); 
                                v.y = 0.5*(vs[i3+1] + vs[j3+1]);
                                v.z = 0.5*(vs[i3+2] + vs[j3+2]);		
	        		v.scaleBy(R/v.length);        
		        	vs.push(v.x,v.y,v.z);		
				uvt.push( (uvt[i3]+uvt[j3])/2, (uvt[i3+1]+uvt[j3+1])/2, 0 );
                               done[e] = n1 = n;
                               n+=1;
                            } else n1 = done[e];
                        
                        e = Math.max(j,k)+""+Math.min(j,k);
                            if ( done[e]==null )
                            {
            			v.x = 0.5*(vs[j3] + vs[k3]); 
                                v.y = 0.5*(vs[j3+1] + vs[k3+1]);
                                v.z = 0.5*(vs[j3+2]+vs[k3+2]);		
		            	v.scaleBy(R/v.length);
        			vs.push(v.x,v.y,v.z);		
	    			uvt.push( (uvt[j3]+uvt[k3])/2, (uvt[j3+1]+uvt[k3+1])/2, 0 );
                                done[e] = n2 = n;
                                n+=1
                            } else n2 = done[e];

                            e = Math.max(k,i)+""+Math.min(k,i);
                            if ( done[e]==null )
                            {                     
        			v.x = 0.5*(vs[k3] + vs[i3]); 
                                v.y = 0.5*(vs[k3+1] + vs[i3+1]);
                                v.z = 0.5*(vs[k3+2]+vs[i3+2]);		
	            		v.scaleBy(R/v.length);
		        	vs.push(v.x,v.y,v.z);		
				uvt.push( (uvt[k3]+uvt[i3])/2, (uvt[k3+1]+uvt[i3+1])/2, 0 );
                                done[e] = n3 = n;
                                n+=1;
                            } else n3 = done[e];
                        
			 fs.push( i, n1, n3 );
			 fs.push( n1, j, n2 );
			 fs.push( n3, n2, k );
			 fs.push( n3, n1, n2 );

			cnt -= 3;
		};
        done = null;
	vsp.length = vs.length/3*2;
        tf.text = tf.text + "\nvertices : "+n;
    }

    public function draw():void
    {
         graphics.clear();
         Utils3D.projectVectors( m3d, vs, vsp, uvt );                   
	 graphics.lineStyle(1,0x000000,0.6,true,LineScaleMode.NONE);
         graphics.beginBitmapFill(s,null,false,true);
         graphics.drawTriangles( vsp, fs, uvt, "positive" );      
    };

    public function ef( evt:Event ):void
    {
        m3d.prependRotation( 15, Vector3D.Y_AXIS );
        m3d.prependRotation( 2, Vector3D.X_AXIS );
        draw();
    }
  }
}