flash on 2014-12-6

by mutantleg
♥0 | Line 303 | Modified 2014-12-06 07:53:14 | MIT License
play

ActionScript3 source code

/**
 * Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/by0Q
 */

package {
    import flash.text.TextField;
    import flash.display.BitmapData;
    import flash.display.StageQuality;
    import flash.geom.Vector3D;
    import flash.geom.Matrix3D;
    import flash.events.Event;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        public function FlashTest() {

            stage.quality = StageQuality.LOW;

            deb = new TextField();
            deb.width =320;
            deb.height=240;
            deb.mouseEnabled=false;
            addChild(deb);
            


            var dat:BitmapData;
            dat = new BitmapData(17,17, false, 0);
            dat.perlinNoise(31,32, 14,15, true,true);
            

            myHeight = new xHeightMap();
            myHeight.cw=16; myHeight.ch=16;

            myHeight.initHeight(dat, 2, -128);


            myHeight.cx = -8*myHeight.cw;
            myHeight.cz = -8*myHeight.ch;
            
            myHeight.initMap(16,16);
            
   
            

            stage.addEventListener(Event.ENTER_FRAME, onEnter);            
        }//ctor
        

        public var frust:xFrustum = new xFrustum();                         
        public var temp:Matrix3D = new Matrix3D();
        public var gt:int = 0;

        public var ang:Number = 0;

        public function onEnter(e:Event):void
        {
           var mx:Number; var my:Number;
           mx = stage.mouseX; my = stage.mouseY; 

           // if (mx < 120) {ang-=3;}
           // if (mx >300) {ang+=3;}
            
           graphics.clear();
           
           graphics.beginFill(0x404040,1);
           graphics.drawRect(0,0,465,465);
           graphics.endFill();
           
           //graphics.lineStyle(1,0);

           gt += 1;
          
             temp.identity();
        //      temp.appendScale(1, 1, 1);
            //   temp.appendRotation(45+ang, Vector3D.Y_AXIS);           
              temp.appendRotation(45+gt*0.5, Vector3D.Z_AXIS);
             //  temp.appendRotation(45, Vector3D.Z_AXIS);
               
               temp.appendRotation(-30, Vector3D.X_AXIS);
       
             myMat = temp.rawData;
       
              drawMesh(myHeight.vecFace, myHeight.vecVert, myMat);     
              
/*
            mx-=scrw; my-=scrh;
            temp.invert();
             myMat = temp.rawData;

            drawSprite(-x,-y,0,8,myMat,0x00FF00);
            
            temp.identity();
            myMat=temp.rawData;
            drawMesh(myHeight.vecFace, myHeight.vecVert, myMat);     
*/
            
/*
           myMat = temp.rawData;
          //  frust.setOrtho(scrw,scrh, 0, 512);
            frust.setOrtho(64, 64, 0, 128);
          
            frust.makeFrustum2(myMat);
            frust.setMouseLine(0,0);
            
            deb.text="";
         //   deb.appendText(" "+frust.retNear.x);
         //   deb.appendText(" "+frust.retNear.y);
          //  deb.appendText(" "+frust.retNear.z);
            deb.appendText(" "+frust.nearCenter.x);
            deb.appendText(" "+frust.nearCenter.y);
            deb.appendText(" "+frust.nearCenter.z);
            deb.appendText(" "+frust.farCenter.x);
            deb.appendText(" "+frust.farCenter.y);
            deb.appendText(" "+frust.farCenter.z);
            
            drawSprite(frust.farCenter.x,frust.farCenter.y,frust.farCenter.z,16,myMat);
            drawSprite(frust.nearCenter.x,frust.nearCenter.y,frust.nearCenter.z,8,myMat);
            drawSprite(frust.farTopLeft.x,frust.farTopLeft.y,frust.farTopLeft.z,16,myMat);
            drawSprite(frust.farBotLeft.x,frust.farBotLeft.y,frust.farBotLeft.z,16,myMat);
            drawSprite(frust.farTopRight.x,frust.farTopRight.y,frust.farTopRight.z,16,myMat);
            drawSprite(frust.farBotRight.x,frust.farBotRight.y,frust.farBotRight.z,16,myMat); 
            
            drawSprite(frust.nearTopLeft.x,frust.nearTopLeft.y,frust.nearTopLeft.z,8,myMat);
            drawSprite(frust.nearBotLeft.x,frust.nearBotLeft.y,frust.nearBotLeft.z,8,myMat);
            drawSprite(frust.nearTopRight.x,frust.nearTopRight.y,frust.nearTopRight.z,8,myMat);
            drawSprite(frust.nearBotRight.x,frust.nearBotRight.y,frust.nearBotRight.z,8,myMat); 
            
           drawSprite(frust.retNear.x,frust.retNear.y,frust.retNear.z,8,myMat,0x00FF00);
            drawSprite(frust.retFar.x,frust.retFar.y,frust.retFar.z,16,myMat,0x00FF00);
            
            */
            
        }//onenter
        
        public var deb:TextField;
           
           
        public var myHeight:xHeightMap;
           
        public var myMat:Vector.<Number> = Vector.<Number>([    
        1, 0, 0, 0,    0, 1, 0, 0,    0, 0, 1, 0,    0, 0, 0, 1]);
       
        public var scrw:Number = 235;
        public var scrh:Number = 235;      
            
        
        public function drawSprite(ax:Number, ay:Number, az:Number, rad:Number, mat:Vector.<Number>, c:uint=0x802343):void
        {
          var sx0:Number; var sy0:Number;
            
          sx0 = ax * mat[0] + ay * mat[4] + az * mat[8] + mat[12];
          sy0 = ax * mat[1] + ay * mat[5] + az * mat[9] + mat[13]; 
            
          graphics.beginFill(c,0.5);  
           graphics.drawCircle(sx0+scrw,sy0+scrh, rad);  
          graphics.endFill();  
            
        }//drawsprite
        
        public function drawMesh(vf:Vector.<int>, vec:Vector.<Number>, mat:Vector.<Number>):void
        {
          var rx:Number; var ry:Number; var rz:Number;
          var sx0:Number; var sy0:Number;
          var sx1:Number; var sy1:Number;
          var sx2:Number; var sy2:Number;
          var wind:Number;
          
          var i:int; var num:int;
          var k:int;
          
          num = vf.length;
        
          for (k = 0; k < num; k += 3)
          {
            i = vf[k] * 3;
            rx = vec[i];        ry = vec[i+1];        rz = vec[i+2];        
             sx0 = rx * mat[0] + ry * mat[4] + rz * mat[8] + mat[12];
             sy0 = rx * mat[1] + ry * mat[5] + rz * mat[9] + mat[13]; 
            //sz = a.cx * mat[2] + a.cy * mat[6] + a.cz * mat[10] + mat[14]; 
           // w = a.cx * mat[3] + a.cy * mat[7] + a.cz * mat[11] + mat[15];          
    
            i = vf[k+1] * 3;
            rx = vec[i];        ry = vec[i+1];        rz = vec[i+2];        
             sx1 = rx * mat[0] + ry * mat[4] + rz * mat[8] + mat[12];
             sy1 = rx * mat[1] + ry * mat[5] + rz * mat[9] + mat[13]; 
    
            i = vf[k+2] * 3;
            rx = vec[i];        ry = vec[i+1];        rz = vec[i+2];        
             sx2 = rx * mat[0] + ry * mat[4] + rz * mat[8] + mat[12];
             sy2 = rx * mat[1] + ry * mat[5] + rz * mat[9] + mat[13]; 
           
            //backface cull -> check winding of verts
              wind = (sx1 - sx0) * (sy2 - sy0) - (sx2 - sx0) * (sy1 - sy0);
              if (wind > 0) { continue; }
    
            graphics.beginFill(rz*0x0000ff, 0.75);
              graphics.moveTo(sx0+scrw, sy0+scrh);
              graphics.lineTo(sx1+scrw, sy1+scrh);
              graphics.lineTo(sx2+scrw, sy2+scrh);
            graphics.endFill();
            
          }//nexti
          
        }//drawmesh2

        
        
        
        
        
    }//classend
}
import flash.display.BitmapData;
import flash.display.Graphics;

internal class xVec
{
  public var x:Number = 0;  public var y:Number = 0;  public var z:Number = 0;
  public function xVec(ax:Number=0,ay:Number=0,az:Number=0)
  { x = ax; y = ay; z = az; }
  public function setValue(ax:Number=0,ay:Number=0,az:Number=0):void
  { x = ax; y = ay; z = az; }
  public function copyVec(a:xVec):void { x=a.x; y=a.y; z=a.z; }
  public function addVec(a:xVec):void { x+=a.x;y+=a.y; z+=a.z; }
  public function subVec(a:xVec):void { x-=a.x;y-=a.y; z-=a.z; }
  public function mulNum(a:Number):void { x*=a; y*=a; z*=a; }
  public function normalise():void 
  { var mag:Number; mag=Math.sqrt(x*x+y*y+z*z);
   if(mag==0){return;} mag=1/mag; x*=mag; y*=mag; z*=mag; }
    public function cross2(a:xVec, b:xVec ):void
    {
      var tx:Number, ty:Number, tz:Number;
        tx = (a.y * b.z) - (a.z * b.y);
        ty = (a.z * b.x) - (a.x * b.z);
        tz = (a.x * b.y) - (a.y * b.x);
        x = tx;            y = ty;            z = tz;
    }//cross2
}//xvec


internal class xFrustum
{
  public var nearWidth:Number, nearHeight:Number;
  public var farWidth:Number, farHeight:Number;
  public var nearDist:Number, farDist:Number;
  
    public var farTopLeft:xVec = new xVec();     public var farBotLeft:xVec = new xVec();  
    public var farTopRight:xVec = new xVec();     public var farBotRight:xVec = new xVec(); 
    
    public var nearTopLeft:xVec = new xVec();     public var nearBotLeft:xVec = new xVec(); 
    public var nearTopRight:xVec = new xVec();     public var nearBotRight:xVec = new xVec(); 

    public var farUp:xVec = new xVec();     public var farSide:xVec = new xVec(); 
    public var nearUp:xVec = new xVec();     public var nearSide:xVec = new xVec(); 
    public var farCenter:xVec = new xVec();     public var nearCenter:xVec = new xVec(); 
   
    public var vecPoint:Vector.<xVec> = Vector.<xVec>([new xVec(),new xVec(),new xVec(),new xVec(),new xVec(),new xVec()]);
    public var vecNorm:Vector.<xVec> = Vector.<xVec>([new xVec(),new xVec(),new xVec(),new xVec(),new xVec(),new xVec()]);

  public function setOrtho(w:Number, h:Number, neard:Number, fard:Number):void
    {
      nearDist = neard;      farDist = fard;
      nearWidth = w;         nearHeight = h;
      farWidth = w;          farHeight = h;
    }//setortho
    
  public function makeFrustum2(mat:Vector.<Number>):void
  {
   var v0:xVec,v1:xVec,v2:xVec,v3:xVec;
    v0=new xVec(); v1=new xVec(); v2=new xVec(); v3=new xVec();  
      
    v0.setValue(mat[0],mat[1],mat[2]);
    v1.setValue(mat[4],mat[5],mat[6]);
    v2.setValue(mat[8],mat[9],mat[10]);
    v3.setValue(mat[12],mat[13],mat[14]);

    makeFrustum(v3, v2, v1, v0); 
         
  }//makefrustum2  
    

 public function makeFrustum(pos:xVec, front:xVec, up:xVec, side:xVec):void
 {
      farUp.copyVec(up); farUp.mulNum(farHeight);
      farSide.copyVec(side); farSide.mulNum(farWidth);
  
      nearUp.copyVec(up); nearUp.mulNum(nearHeight);
      nearSide.copyVec(side); nearSide.mulNum(nearWidth);
      
      farCenter.copyVec(front); farCenter.mulNum(farDist);
      farCenter.addVec(pos);
        
        farTopLeft.copyVec(farCenter); farTopLeft.addVec(farUp); farTopLeft.subVec(farSide);
        farTopRight.copyVec(farCenter); farTopRight.addVec(farUp); farTopRight.addVec(farSide);
        farBotLeft.copyVec(farCenter); farBotLeft.subVec(farUp); farBotLeft.subVec(farSide);
        farBotRight.copyVec(farCenter); farBotRight.subVec(farUp); farBotRight.addVec(farSide);
        
      nearCenter.copyVec(front); nearCenter.mulNum(nearDist);
      nearCenter.addVec(pos);
      
        nearTopLeft.copyVec(nearCenter); nearTopLeft.addVec(nearUp); nearTopLeft.subVec(nearSide);
        nearTopRight.copyVec(nearCenter); nearTopRight.addVec(nearUp); nearTopRight.addVec(nearSide);
        nearBotLeft.copyVec(nearCenter); nearBotLeft.subVec(nearUp); nearBotLeft.subVec(nearSide);
        nearBotRight.copyVec(nearCenter); nearBotRight.subVec(nearUp); nearBotRight.addVec(nearSide);
       
        //near
          vecPoint[0].copyVec(nearCenter);
          vecNorm[0].copyVec(farCenter); vecNorm[0].subVec(nearCenter);
          vecNorm[0].normalise();
        //far
          vecPoint[1].copyVec(farCenter);
          vecNorm[1].copyVec(nearCenter); vecNorm[1].subVec(farCenter);
          vecNorm[1].normalise();    
        //left
          calcPlane(nearTopLeft, nearBotLeft, farBotLeft, vecPoint[2], vecNorm[2]);
          addPos(farBotLeft, nearTopLeft, vecPoint[2]);
        //right
          calcPlane(nearBotRight, nearTopRight, farBotRight, vecPoint[3], vecNorm[3]); 
          addPos(farTopRight, nearBotRight, vecPoint[3]);
        //top
          calcPlane(nearTopRight, nearTopLeft, farTopLeft, vecPoint[4], vecNorm[4]); 
          addPos(farTopLeft, nearTopRight, vecPoint[4]);
        //bottom
          calcPlane(nearBotLeft, nearBotRight, farBotRight, vecPoint[5], vecNorm[5]);
          addPos(farBotRight, nearBotLeft, vecPoint[5]);    
    }//makefrustum


    private var e0:xVec = new xVec();
    private var e1:xVec = new xVec();
    public function calcPlane(p0:xVec, p1:xVec, p2:xVec, p:xVec, n:xVec):void
    {
      
      e0.copyVec(p1); e0.subVec(p0);
      e1.copyVec(p2); e1.subVec(p0);
      p.copyVec(p0);          n.cross2(e0, e1);
      n.mulNum( -1);
      n.normalise();
    }//calcplane
  
    public function addPos(p0:xVec, p1:xVec, ret:xVec):void
    {
      ret.x += (p0.x - p1.x) * 0.5;
      ret.y += (p0.y - p1.y) * 0.5;
      ret.z += (p0.z - p1.z) * 0.5;
    }//setpos
    
    private var tmp0:xVec = new xVec();
    public var retNear:xVec = new xVec();
    public var retFar:xVec = new xVec();
    public function setMouseLine(umx:Number, umy:Number ):void
    {
      retNear.copyVec(nearCenter);
      tmp0.copyVec(nearUp); tmp0.mulNum(umy); retNear.addVec(tmp0);
      tmp0.copyVec(nearSide); tmp0.mulNum(umx); retNear.addVec(tmp0);
      
      retFar.copyVec(farCenter);
      tmp0.copyVec(farUp); tmp0.mulNum(umy); retFar.addVec(tmp0);
      tmp0.copyVec(farSide); tmp0.mulNum(umx); retFar.addVec(tmp0);  
    }//setmouseline
    
}//xfrustum



internal class xHeightMap
{
    public var vecHeight:Vector.<Number>;
    public var vecVert:Vector.<Number>;
    public var vecFace:Vector.<int>;

    //face grid size    
    public var mw:int = 0;    public var mh:int = 0;

    //height grid size
    public var vmw:int = 0;    public var vmh:int = 0;
    
    public var cw:Number = 32;    public var ch:Number = 32;
    public var cx:Number = 0;
    //public var cy:Number = 0;
    public var cz:Number = 0;
    
    
    public function initHeight(bdat:BitmapData, sy:Number=1, ay:Number=0):void
    {
      var i:int; var k:int;
      var w:int; var h:int;
      var yt:int;
      var num:int;
      w = bdat.width; h = bdat.height;
      num = w * h;
      vecHeight = new Vector.<Number>(num,false);
       for (i = 0; i < h; i++)
       {
            yt = i*w;            
        for (k = 0; k < w; k++)
        {
            vecHeight[k+yt] = (bdat.getPixel(k,i) & 0xFF) * sy + ay;            
        }//nextk
       }//nexti
      
      
    }//initheight
    

    //note  -- w and h is for the number of quads    
    public function initMap(w:int, h:int):void
    {
        mw = w; mh = h;
        vmw = w+1; vmh = h+1;
        var i:int; var k:int; var num:int;
        var w:int; var yt:int;
        num = mw*mh;
        vecFace = new Vector.<int>(num,false);
            
       w = 0;
       for (i = 0; i < mh; i++)
       {
            yt = i*(mw+1);            
        for (k = 0; k < mw; k++)
        {
              vecFace[w] = 0 + k + yt; //0
              vecFace[w+1] = 0 + k + (mw+1) + yt; //1
              vecFace[w+2] = 1 + k + yt; //2
                                
              vecFace[w+3] = 1 + k + yt; //2
              vecFace[w+4] = 0 + k + (mw+1) + yt; //1
              vecFace[w+5] = 1 + k + (mw+1) + yt; //3

              w+=6;      
            }//nextk
        }//nexti
            
        num = (mw+1)*(mh+1);
        if (vecHeight == null) 
        {
           vecHeight = new Vector.<Number>(num,false);
          for(i= 0;i <num;i++){vecHeight[i]=Math.random()*3;}   
        }
        
        vecVert = new Vector.<Number>(num*3,false);      
            
        w = 0;
       for (i = 0; i < (mh+1); i++)
       {
            yt = i*(mw+1);            
        for (k = 0; k < (mw+1); k++)
        {
            vecVert[w] = k*cw + cx;
            vecVert[w+2] = vecHeight[yt+k];
            vecVert[w+1] = i * ch + cz;    
            w+=3;
        }//nextk
       }//nexti     
            
    }//initmap
    
 
    public function getHeight(ax:Number, az:Number):Number
        {
            var tx:int;            var ty:int; var yt:int;
            
            ax -= cx; az -=cz; //transform by heightmap coords first
            
            tx = Math.floor(ax/cw);            ty = Math.floor(az/ch);
            
            var h0:Number;    var h1:Number;             
            var z0:Number; var z1:Number;
            var u:Number; var v:Number;
            
            if (tx < 0) { return 0; }            if (ty < 0) { return 0; }
            if (tx + 1 >= mw) { return 0; }      if (ty + 1 >= mh) { return 0; }
            
            yt = ty * vmw;
            
            u = (ax/cw)-tx;            v = (az/ch)-ty;
            z0 = vecHeight[yt+tx];      z1 = vecHeight[yt+tx+1];
            h0 = z0 + (z1-z0)*u;
            
            z0 = vecHeight[yt+tx+vmw];      z1 = vecHeight[yt+tx+vmw+1];
            h1 = z0 + (z1 -z0)*u;
            
            return (h0 +(h1-h0) * v); 
            
        }//getheight
    
    
}//xheightmap