Tilemap Stage3D version

by mutantleg
it's a cobbled together version of the tilemap example; could use some major cleanup (also the uv coordinates are not set yet, but will use the same idea as in the bitmapdata based version http://wonderfl.net/c/vyIQ )

The idea is that from the camera matrix and projection we calculate the  start and end  coordinates where the tilemap should be drawn, the tilemap itself is a 3D object and the triangles are recalculated and uploaded every frame
♥0 | Line 673 | Modified 2013-01-30 18:20:22 | 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/cVdj
 */

package {
    import flash.ui.Keyboard;
    import flash.geom.*;
    import flash.display.*;
    import flash.utils.ByteArray;
    import flash.events.*;
    import flash.text.TextField;
    import com.adobe.utils.AGALMiniAssembler;
    import flash.display3D.*;
    import flash.display3D.textures.Texture;
    public class FlashTest extends Sprite {
        
        public static var deb:TextField;
        
        public var deb2:TextField;
        
        
        public function FlashTest() {
 
            deb = new TextField();
            addChild(deb);
            deb.width = 400;
            deb.text = " debug ";
            deb.y = 250;
            
            
            
            deb2 = new TextField();
            addChild(deb2);
            deb2.width= 400;
            deb2.text = "debug2";
            deb2.y = 300;
            
            
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }//ctor
        
        public function init(e:Event=null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            //if (stage == null) { deb.text = "stage null"; }
           // else { deb.text = "stage exist"; }
            //deb.text = "stage > " + stage.stage3Ds[0];
            
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, contReady);
            stage.stage3Ds[0].addEventListener(ErrorEvent.ERROR, onError);
            stage.stage3Ds[0].requestContext3D(Context3DRenderMode.AUTO);
            
           // deb.text = " reach ";
        }//init
    
        private var context:Context3D;
        
        public function onError(e:ErrorEvent):void
        {
            deb.text = e.text;
            deb.textColor = 0xFF0000FF;
        }//onerror
        
        public function contReady(e:Event):void
        {
            deb.text = "context ready ";
            
            context = stage.stage3Ds[0].context3D;
            deb.text = context.driverInfo;
            //deb.textColor = 0xFFffFFff;
            
            context.addEventListener(ErrorEvent.ERROR, onError);
            
        
            context.configureBackBuffer(200, 200, 2, true);
        
        
            initProgram(context);    
            
            myTex = new wTex();       
                myTex.genTex(myTex.getXor(64,64), context);
           
           ptex = new wTex();
           ptex.genTex(new BitmapData(32,32,false,0xFFffFFff),context); 
           
           
            geo = new wGeo();
            //geo.makeSprite();                        
           // geo.makeCube();
           geo.makeTmap();
           
            geo.upload(context);
          
            pgeo = new wGeo();
            pgeo.makeSprite();
            pgeo.upload(context);
          
             
             tmap = new wTileMap();
             tmap.makeBuf(context);
             tmap.setMap(0,0, 10,10);
             tmap.update();
          

            var pic:Bitmap;
            pic = new Bitmap(new BitmapData(200,200,false,0));
            context.clear();
            draw(context);
            context.drawToBitmapData(pic.bitmapData);
            //context.present();            
            addChild(pic);
            pic.x = 200;
            pic.y = 100;
        
            stage.addEventListener(Event.ENTER_FRAME, onEnter);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, kdown);
            stage.addEventListener(KeyboardEvent.KEY_UP, kup);
        }//contready
        
        public var vecKey:Vector.<Boolean> = new Vector.<Boolean>(512, false);
        public function kdown(e:KeyboardEvent):void { vecKey[e.keyCode] = true; }
        public function kup(e:KeyboardEvent):void { vecKey[e.keyCode] = false; }        
        
        public var tmap:wTileMap;
        
        
        public var prog:Program3D;
        public var myTex:wTex;
        
        public var geo:wGeo;
        
        public var pgeo:wGeo;
        public var ptex:wTex;
        
        public function initProgram(c:Context3D):void
        { 
            prog = c.createProgram();
                       
            var vert:ByteArray;
            var frag:ByteArray;
            var assembler:AGALMiniAssembler = new AGALMiniAssembler();
            
            var code:String;
                code = "";
                code += "m44 op, va0, vc0\n";
               // code += "m44 v0, va1, vc4\n";
                //code += "move v0, va1\n";
                code += "m44 v0, va1, vc4\n"
              //  code += "move v1, va2\n";
                
                    vert = assembler.assemble(Context3DProgramType.VERTEX, code);
                
                code = "";
                code += "tex ft0 v0, fs0 <2d, linear, miplinear, wrap>\n";
                //code += "move oc, v0\n";
                code += "mov oc, ft0\n";
                //code += "mul oc, ft0, v0\n";
                //code += "mul oc, v0, fc0\n";
                //code += "move oc, fc0\n";
                
                    frag = assembler.assemble(Context3DProgramType.FRAGMENT, code);

            prog.upload(vert, frag);
 
        }//initprogram;
        
        public var cx:Number = 0;
        public var cy:Number = 2;
        public var vx:Number = 0;
        public var vy:Number = 0;
        
     public var bOverObst:Boolean = false;       
        public function onEnter(e:Event):void
        {
            if (vecKey[Keyboard.UP]) { vy += 0.1; }
            if (vecKey[Keyboard.DOWN]) { vy -= 0.1; }
            if (vecKey[Keyboard.LEFT]) { vx -= 0.1; }
            if (vecKey[Keyboard.RIGHT]) { vx += 0.1; }

            vx *= 0.92;
            vy *= 0.92;
            
            bOverObst = false;
            if (tmap.isWall(cx,cy) ) { bOverObst = true;}
            
            /*
            if (vx > 0 && tmap.isWall(cx+0.5,cy) ) { vx = 0; }
            if (vx < 0 && tmap.isWall(cx-0.5,cy) ) { vx = 0; }
            if (vy > 0 && tmap.isWall(cx,cy+0.5) ) { vy = 0; }
            if (vy < 0 && tmap.isWall(cx,cy-0.5) ) { vy = 0; }
*/
            
            
            cx += vx;
            cy += vy;
            
            
            context.clear();
            
            draw(context);          
                      
            context.present();
        }//onenter
        
        
        public var projmat:Matrix3D = new Matrix3D();
        public var cammat:Matrix3D = new Matrix3D();
        public var mat:Matrix3D = new Matrix3D();
        public var texMat:Matrix3D = new Matrix3D();
        public var ang:Number = 0;
        public var spin:Number = 0;
        public function draw(c:Context3D):void
        {
            var color:Vector.<Number> = Vector.<Number>([1.0,1.0,1.0,1.0]);
            var raw:Vector.<Number>;
            
           // c.setCulling(Context3DTriangleFace.BACK);
            c.setCulling(Context3DTriangleFace.NONE);
            
            c.setProgram(prog);
           
           spin += 5;
           
           mat.identity();
           mat.appendTranslation(0,0,0);
          // mat.appendRotation(spin, Vector3D.Y_AXIS);
          // mat.appendRotation(spin, Vector3D.X_AXIS);
           
           cammat.identity();
          // cammat.appendTranslation(0,0, -9); // -2 + Math.cos(ang)-1);
                       
           cammat.appendTranslation(-cx, -cy, -9); // -2 + Math.cos(ang)-1);
             cammat.appendRotation(30, Vector3D.Z_AXIS);
             
           setProjectionMatrix(projmat,90,1,0.1,100);
           raw = cammat.rawData;
                
           deb2.text = "";
           deb2.appendText(" cx "+ -cx + " cy " + -cy + " cz " + -9);
           deb2.appendText("\n raw " + raw[12] + " " + raw[13] + "  " + raw[14]);
           
          
           calcFrust(90, 1, 0.1, 100,
              cx, cy, -9, //-5, //-9, 
              //-raw[12], -raw[13], raw[14],
              /*0,0,1,
              0,1,0,
              1,0,0);
              */
              
            raw[2], raw[6], raw[10],
            raw[1], raw[5], raw[9],
            raw[0], raw[4], raw[8]);
              
              /*
            raw[8], raw[9], raw[10],
            raw[4], raw[5], raw[6],
            raw[0], raw[1], raw[2]);
            */
/*
   raw[2], raw[6], raw[10],
            raw[1], raw[5], raw[9],
            raw[0], raw[4], raw[8]);
*/

/*
            var temp:Number;
            temp = maxy;
            maxy = miny;
            miny = temp;
*/
            deb.text = " ";
            deb.appendText("\n x " +minx+ "  y " + miny);
            deb.appendText("\n x " +maxx+ "  y " + maxy);


 //          tmap.setMap(Math.floor(minx),Math.floor(miny),
  //         Math.ceil(maxx), Math.ceil(maxy) );
        //   tmap.setMap(0,0,3,3);
          // tmap.setMap(0,0,maxx, -miny);
          // tmap.setMap(minx, -maxy, 10,10);
           tmap.setMap(minx, -maxy, maxx+1, -miny+1);
           tmap.update();
           
                       
            
            mat.append(cammat);
            mat.append(projmat);
            
            ang += 0.03;
            
            var vec:Vector.<Number>;
            var s:Number;
            
            texMat.identity();
            
           // texMat.appendTranslation(-0.5,-0.5,0);
         
            
            //texMat.appendRotation(Math.cos(ang)*180.0, Vector3D.Z_AXIS);
              s = Math.sin(ang)+2;
            //texMat.appendScale(s,s,s);  
              
          //  texMat.appendTranslation(0.5,0.5,0);
            
      
            
           //draw tilemap  (debug)
            c.setTextureAt(0, myTex.tex);
            
            c.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mat, true); 
            c.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 4, texMat, true);
            c.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, color);

 //           c.setVertexBufferAt(0, geo.bufVert, 0, Context3DVertexBufferFormat.FLOAT_3);    
  //          c.setVertexBufferAt(1, geo.bufUv, 0, Context3DVertexBufferFormat.FLOAT_2);
            
//            c.drawTriangles(geo.bufFace, 0, geo.numFace);
 
         //draw tilemap
          mat.identity();
          mat.appendTranslation(0, 0, 0);
           mat.append(cammat);
           mat.append(projmat);
           
          c.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mat, true); 
 
            c.setVertexBufferAt(0, tmap.bufVert, 0, Context3DVertexBufferFormat.FLOAT_3);    
            c.setVertexBufferAt(1, tmap.bufUv, 0, Context3DVertexBufferFormat.FLOAT_2);
            
            c.drawTriangles(tmap.bufFace, 0, tmap.numTile*2);
            
            
     
     
         //draw player
           mat.identity();
           if (bOverObst) {  mat.appendRotation(45, Vector3D.Z_AXIS);  } 
          
           mat.appendTranslation(cx,cy,0.001);
           
          // if (bOverObst) {  mat.appendRotation(45, Vector3D.Z_AXIS);  } 
           
           
           mat.append(cammat);
           mat.append(projmat);
 
           c.setTextureAt(0, ptex.tex);
           c.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mat, true); 
 
            c.setVertexBufferAt(0, pgeo.bufVert, 0, Context3DVertexBufferFormat.FLOAT_3);    
            c.setVertexBufferAt(1, pgeo.bufUv, 0, Context3DVertexBufferFormat.FLOAT_2);
            
            c.drawTriangles(pgeo.bufFace, 0, pgeo.numFace);
      
             drawPoint(c,minx, miny);
             drawPoint(c,maxx, maxy);
            
        }//draw
        
        public function drawPoint(c:Context3D, wx:Number, wy:Number):void
        {
           mat.identity();
           mat.appendTranslation(wx,wy,0.001);
           mat.append(cammat);
           mat.append(projmat);
         
           c.setTextureAt(0, ptex.tex);
           c.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mat, true); 
 
            c.setVertexBufferAt(0, pgeo.bufVert, 0, Context3DVertexBufferFormat.FLOAT_3);    
            c.setVertexBufferAt(1, pgeo.bufUv, 0, Context3DVertexBufferFormat.FLOAT_2);
            
            c.drawTriangles(pgeo.bufFace, 0, pgeo.numFace);
      
        }//drawpoint
        
      
        
        
        
      public function setProjectionMatrix(m:Matrix3D,
        fovdeg:Number = 90.0, aspect:Number=1.0, nearp:Number = 0.1, farp:Number=1000.0):void
        {
            var vec:Vector.<Number> = m.rawData;
            var f:Number;
            var i:int;

            for (i = 0; i < 16; i++) { vec[i] = 0.0;  } 

            f = 1.0 / Math.tan( (fovdeg * (3.1415 / 180.0)) * 0.5 );

            if (nearp == 0) { nearp = 0.0001; }
            if (farp == 0) { farp = 0.0001; }

            vec[0] = f / aspect;
            vec[5] = f;
            vec[10] = (farp + nearp) / (nearp - farp);
            vec[14] = (2.0 * farp * nearp) / (nearp - farp);
            vec[11] = -1.0;
            vec[15] = 0.0;

            m.rawData = vec;
        }//projmatrix
            
            
        public var minx:Number = 0;
        public var miny:Number = 0;
        public var maxx:Number = 0;
        public var maxy:Number = 0;  
        
        public function calcFrust(
        fov:Number, aspect:Number, neard:Number, fard:Number,
        posx:Number, posy:Number, posz:Number,
        frontx:Number, fronty:Number, frontz:Number,
        upx:Number, upy:Number, upz:Number,
        sidex:Number, sidey:Number, sidez:Number):void
        {
            var nw:Number;
            var nh:Number;
            var fw:Number;
            var fh:Number;
            var tang:Number;
            
            var fupx:Number, fupy:Number, fupz:Number;
            var fsidex:Number, fsidey:Number, fsidez:Number;
            var nupx:Number, nupy:Number, nupz:Number;
            var nsidex:Number, nsidey:Number, nsidez:Number;
            
            var fcx:Number, fcy:Number, fcz:Number;
            var ncx:Number, ncy:Number, ncz:Number;
            
            fov *= 3.1415 / 180;
            tang = Math.tan ( fov * 0.5 );

            nh = neard * tang;
            nw = nh * aspect;
            
            fh = fard * tang;
            fw = fh * aspect;
             
            fupx = upx * fh;
            fupy = upy * fh;
            fupz = upz * fh;
            
            fsidex = sidex * fw;
            fsidey = sidey * fw;
            fsidez = sidez * fw;
            
            nupx = upx * nh;
            nupy = upy * nh;
            nupz = upz * nh;
            
            nsidex = sidex * nw;
            nsidey = sidey * nw;
            nsidez = sidez * nw;
            
            fcx = posx + frontx * fard;
            fcy = posy + fronty * fard;
            fcz = posz + frontz * fard;
            
            ncx = posx + frontx * neard;
            ncy = posy + fronty * neard;
            ncz = posz + frontz * neard;
            
            
            var ax:Number;
            var ay:Number;
            var az:Number;
            var bx:Number;
            var by:Number;
            var bz:Number;
           
            var t:Number;
            var kx:Number;
            var ky:Number;
            var kz:Number;
            
            minx = 999999;
            miny = 999999;
            maxx = -999999;
            maxy = -999999;
            
            
         
            ax = ncx + (nupx*1)+(nsidex*1);
            ay = ncy + (nupy*1)+(nsidey*1); 
            az = ncz + (nupz*1)+(nsidez*1);
            
            bx = fcx + (fupx*1)+(fsidex*1);
            by = fcy + (fupy*1)+(fsidey*1);
            bz = fcz + (fupz*1)+(fsidez*1);
            
            t =  (az / -(bz - az));
            kx = ax + (bx-ax)*t;
            ky = ay + (by-ay)*t;
            graphics.drawCircle(kx,ky,4);
            //kz = az + (bz-ay)*t;
            minx =  minx < kx ? minx : kx; //   Math.min(minx, kx);
            miny =  miny < ky ? miny : ky; // Math.min(miny, ky);
            maxx = maxx > kx ? maxx : kx; // Math.max(maxx, kx);
            maxy = maxy > ky ? maxy : ky; // Math.max(maxx, ky);     
            
            graphics.drawCircle(ncx,ncy, 8);
            graphics.drawCircle(ax,ay, 4);
            graphics.drawCircle(bx,by,2);
            
   
            ax = ncx + (nupx*-1)+(nsidex*1);
            ay = ncy + (nupy*-1)+(nsidey*1); 
            az = ncz + (nupz*-1)+(nsidez*1);
            
            bx = fcx + (fupx*-1)+(fsidex*1);
            by = fcy + (fupy*-1)+(fsidey*1);
            bz = fcz + (fupz*-1)+(fsidez*1);
           // graphics.drawCircle(bx,by,2);
       
            t =  (az / -(bz - az));
            kx = ax + (bx-ax)*t;
            ky = ay + (by-ay)*t;
           // graphics.drawCircle(kx,ky,4);
           
            minx =  minx < kx ? minx : kx; 
            miny =  miny < ky ? miny : ky; 
            maxx = maxx > kx ? maxx : kx; 
            maxy = maxy > ky ? maxy : ky;  
            
            
            
            ax = ncx + (nupx*-1)+(nsidex*-1);
            ay = ncy + (nupy*-1)+(nsidey*-1); 
            az = ncz + (nupz*-1)+(nsidez*-1);
   
            bx = fcx + (fupx*-1)+(fsidex*-1);
            by = fcy + (fupy*-1)+(fsidey*-1);
            bz = fcz + (fupz*-1)+(fsidez*-1);
            //graphics.drawCircle(bx,by,2);

            t =  (az / -(bz - az));
            kx = ax + (bx-ax)*t;
            ky = ay + (by-ay)*t;
            //graphics.drawCircle(kx,ky,4);
           
            minx =  minx < kx ? minx : kx; 
            miny =  miny < ky ? miny : ky; 
            maxx = maxx > kx ? maxx : kx; 
            maxy = maxy > ky ? maxy : ky;  
            
            
            
            ax = ncx + (nupx*1)+(nsidex*-1);
            ay = ncy + (nupy*1)+(nsidey*-1); 
            az = ncz + (nupz*1)+(nsidez*-1);
   
                
            bx = fcx + (fupx*1)+(fsidex*-1);
            by = fcy + (fupy*1)+(fsidey*-1);
            bz = fcz + (fupz*1)+(fsidez*-1);
           // graphics.drawCircle(bx,by,2);

            t =  (az / -(bz - az));
            kx = ax + (bx-ax)*t;
            ky = ay + (by-ay)*t;
            //graphics.drawCircle(kx,ky,4);
           
            minx =  minx < kx ? minx : kx; 
            miny =  miny < ky ? miny : ky; 
            maxx = maxx > kx ? maxx : kx; 
            maxy = maxy > ky ? maxy : ky;  


            //graphics.drawCircle(minx,miny, 16);
            //graphics.drawCircle(maxx, maxy, 16);            
        
           // graphics.drawRect(minx,miny, maxx-minx, maxy-miny);    
            
        }//calcmouse
        
        
        
        
        
        
        
        
        
    }//classend
}



import flash.events.ErrorEvent;
import flash.geom.Matrix;
import flash.display.BitmapData;

  import flash.display3D.textures.Texture;
  import flash.display3D.*;

internal class wTex
{
    public var tex:Texture = null;
    
    
    public function wTex() {}
    
    public function getXor(w:int, h:int):BitmapData
    {
        var bm:BitmapData;
        var k:int;
        var i:int;
        
        bm = new BitmapData(w,h,false,0);
        
        for (i = 0; i < h; i++)
        {
            for (k = 0; k < w; k++)
            {
                bm.setPixel(k,i, (i^k)<<16 | (i ^ k) << 8 | (i^k));
                
            }//nextk
        }//nexti
        
        return bm;
    }//getxor
   
    
    public function genTex(bm:BitmapData, c:Context3D):void
    {
      var s:int; //scale
      var m:int; //miplevel
            
                      
      if (bm.width % 2 != 0 || bm.height %2 != 0 || bm.width != bm.height) 
      {
           bm = getResized(bm, 64, 64);   
      }//endif
      
      tex = c.createTexture(bm.width, bm.height, Context3DTextureFormat.BGRA, false);
      
    
      tex.uploadFromBitmapData( bm , 0);
      
   
       m = 1;
       s = bm.width*0.5;

      while (s > 0)
      {
            tex.uploadFromBitmapData(getResized(bm, s, s), m);
            m += 1;
            s *= 0.5;
      }//wend
        
    }//gentex
    
    private var tempMat:Matrix = new Matrix();

    private function getResized(bm:BitmapData, w:int, h:int):BitmapData
        {
            var ret:BitmapData;
            var mat:Matrix;
            
            mat = tempMat;
            //mat.identity();
            mat.a = w / bm.width;
            mat.d = h / bm.height;

            ret = new BitmapData(w, h, bm.transparent, 0);
            ret.draw(bm, mat, null, null, null, true);

            return ret;
        }//getresized
    
};//classend

internal class wTileMap
{
    public var vecVert:Vector.<Number> ;
    public var vecUv:Vector.<Number> ;
    public var vecFace:Vector.<uint> ;
    
    public var bufVert:VertexBuffer3D;
    public var bufUv:VertexBuffer3D;
    public var bufFace:IndexBuffer3D;
    
    public var mwidth:int = 0;
    public var mheight:int = 0;
    public var vecMap:Vector.<int> = null;
    
    public var maxTile:int = 1024; //max tiles to display
    public var numTile:int = 0; //number of tiles displayed
    
    public function wTileMap()
    {
        /*
      mwidth = 2;
      mheight = 2;
      vecMap = Vector.<int>([0,0,0,0]); 
       */
       
       mwidth = 7;
       mheight = 6;
        
        vecMap =
        Vector.<int>([
        1,1,1,1,1,0,1,
        1,0,0,0,0,0,1,
        1,0,1,1,1,1,1,
        1,0,1,0,0,1,1,
        1,0,1,1,0,1,0,
        1,0,0,0,0,0,0 ]);
        
        //randmap
        
        mwidth = 64;
        mheight = 64;
        var num:int;
        var i:int;
        num = mwidth * mheight;
        
        vecMap = new Vector.<int>(num, 0);
        
        for (i = 0; i < num; i++)
        {
            vecMap[i] = Math.random() * 2;
        }//nexti
        
    }//ctor  
    
    //create default buffers
    public function makeBuf(c:Context3D):void
    {
       vecVert = new Vector.<Number>(maxTile*3*4,false);
       vecUv = new Vector.<Number>(maxTile*2*4, false);
       vecFace = new Vector.<uint>(maxTile*3*2, false) ;
       
       var nf:int;
       var i:int;
       var k:int;
       
       nf = maxTile*3*2;
       k = 0;
       for (i = 0; i < nf; i+=6)
       {
           vecFace[i] = 0+k;
           vecFace[i+1] = 1+k;
           vecFace[i+2] = 2+k;
           
           vecFace[i+3] = 1+k;
           vecFace[i+4] = 3+k;
           vecFace[i+5] = 2+k;
           
           k += 4;
       }//nexti
       
        bufVert = c.createVertexBuffer(maxTile*4, 3);
        bufUv = c.createVertexBuffer(maxTile*4, 2);
        bufFace = c.createIndexBuffer(maxTile*3);
      
        bufVert.uploadFromVector(vecVert, 0, maxTile*4);
        bufFace.uploadFromVector(vecFace, 0, maxTile * 3);
        bufUv.uploadFromVector(vecUv, 0, maxTile*4);
        
    }//makebuf
    
    
    //update vertex buffer
    public function update():void
    {
         bufVert.uploadFromVector(vecVert, 0, numTile*4);
          bufUv.uploadFromVector(vecUv, 0, numTile*4);
    }//update
    
    public function setMap(sx:int, sy:int, ex:int, ey:int):void
    {
        var k:int;
        var i:int;
        var yt:int;
        
        var curc:int; //current texcoord
        var curv:int; //current vertex
        var curt:int; //current tile
        var t:int;
        
        
        if (sx >= mwidth) { return; }
        if (sy >= mheight) { return; }
        if (ex < 0) { return; }
        if (ey < 0) { return; }
        
        
        if (sx < 0) { sx = 0; }
        if (sy < 0) { sy = 0; }
        if (ex > mwidth) { ex = mwidth; }
        if (ey > mheight) { ey = mheight; }
        
        
        curc = 0;
        curt = 0;
        curv = 0;
       
        
        for (i = sy; i < ey; i++)
        {
            yt = i * mwidth;
            for (k = sx; k < ex; k++)
            {
                t = vecMap[yt+k];
                if (t <= 0) { continue; }
                
                vecVert[curv] = k;
                vecVert[curv+1] = -i;
                //vecVert[curv+2] = 0;
                vecUv[curc] = 0;
                vecUv[curc+1] = 0;
                
                vecVert[curv+3] = k;
                vecVert[curv+4] = -i - 1;
                //vecVert[curv+5] = 0;
                vecUv[curc+2] = 1;
                vecUv[curc+3] = 0;
                
                vecVert[curv+6] = k+1;
                vecVert[curv+7] = -i;
                //vecVert[curv+8] = 0;
                vecUv[curc+4] = 0;
                vecUv[curc+5] = 1;
                
                vecVert[curv+9] = k+1;
                vecVert[curv+10] = -i - 1;
                //vecVert[curv+11] = 0;
                vecUv[curc+6] = 1;
                vecUv[curc+7] = 1;
                
                /*
                    addQuad(
               [k,-i,0, 0,0],
               [k,-i-1,0, 1,0],
               [1+k,-i,0, 0,1],
               [1+k,-i-1,0, 1,1]);          
   */
               curc += 8;  //2+2+2+2
               curv += 12;  //3+3+3+3
               curt += 1;
               if (curt >= maxTile) { numTile = curt; return; }
                
            }//nexti
        }//nexti
        
        numTile = curt;
        
    }//setmap
    
    public function isWall(wx:Number, wy:Number):Boolean
    {
        var tx:int;
        var ty:int;
        
        tx = Math.floor(wx);
        ty = Math.floor(-wy);
        
        if (tx < 0) { return false; }
        if (ty < 0) { return false; }
        if (tx >= mwidth) { return false; }
        if (ty >=mheight) { return false; }
        
        return (vecMap[ty*mwidth +tx] > 0 );
        
    }//iswall
    
}//classendtmap

internal class wGeo
{
    public var vecVert:Vector.<Number> ;
    public var vecUv:Vector.<Number> ;
    public var vecFace:Vector.<uint> ;
    
    public var bufVert:VertexBuffer3D;
    public var bufUv:VertexBuffer3D;
    public var bufFace:IndexBuffer3D;
    
    public var numFace:int = 0;
    
        public var mwidth:int = 7;
        public var mheight:int = 6;
        
        //using a picture of an F
        //so i can easily tell the orientation of this thing
        public var vecMap:Vector.<int> =
        Vector.<int>([
        1,1,1,1,1,1,1,
        1,0,0,0,0,0,1,
        1,0,0,1,1,1,1,
        1,0,0,0,0,1,1,
        1,0,0,1,1,1,0,
        1,0,0,1,1,0,0 ]);
     
        
     
     
    public function wGeo()
    {}//ctor
    
    public function upload(c:Context3D):void
    {
        if (bufVert != null) { bufVert.dispose(); }
        if (bufUv != null) { bufUv.dispose(); }
        if (bufFace != null) { bufFace.dispose(); }
        
        var numVert:int;
       // var numFace:int;
        
        numVert = Math.floor( vecVert.length / 3);
        numFace = Math.floor( vecFace.length / 3);
        
        bufVert = c.createVertexBuffer(numVert, 3);
        bufUv = c.createVertexBuffer(numVert, 2);
        bufFace = c.createIndexBuffer(numFace*3);
      
        bufVert.uploadFromVector(vecVert, 0, numVert);
        bufFace.uploadFromVector(vecFace, 0, numFace * 3);
     
        bufUv.uploadFromVector(vecUv, 0, numVert);
        
    }//upload

    public function isWall(wx:Number, wy:Number):Boolean
    {
        var tx:int;
        var ty:int;
        
        tx = Math.floor(wx);
        ty = Math.floor(-wy);
        
        if (tx < 0) { return false; }
        if (ty < 0) { return false; }
        if (tx >= mwidth) { return false; }
        if (ty >=mheight) { return false; }
        
        return (vecMap[ty*mwidth +tx] > 0 );
        
    }//iswall


    //make tilemap based on the vecmap vector
    public function makeTmap():void
    {
        var i:int;
        var k:int;
        var yt:int;
        var t:int;
        
        vecFace = new Vector.<uint>;
        vecVert = new Vector.<Number>;
        vecUv = new Vector.<Number>;
     
      //  addQuad([0,,p, 0,0], [0,p,p, 1,0], [p,0,p, 0,1], [p,p,p, 1,1]);          
        
        /*
          addQuad([0, 1, 0, 0, 0 ],
                  [1, 0, 0, 1, 0 ],
                  [0, 1, 0, 0, 1 ],
                  [1, 1, 0, 1, 1 ] );
        */
           var n:Number;
        var p:Number;
        
        n = -0.5;
        p = 0.5;
        
        //just some indicator on where 0,0 is
        addQuad([n,n,0, 0,0],[n,p,0, 1,0],[p,n,0, 0,1],[p,p,0, 1,1]);          
         
        
        
//        return;
        
        n = 0;
        p = 1;
        
        for (i = 0; i < mheight; i++)
        {
            yt = i * mwidth;
            
            for (k = 0; k < mwidth; k++)
            {
                t = yt + k;
                if (vecMap[t] <= 0) { continue; }
 
               addQuad(
               [k,-i,0, 0,0],
               [k,-i-1,0, 1,0],
               [1+k,-i,0, 0,1],
               [1+k,-i-1,0, 1,1]);          
   
        
            }//nextk
            
        }//nexti
        
    }//maketmap


    //make quad (2 tris)
    public function makeSprite():void
    {
            var p:Number;
            var n:Number;
            var scale:Number;
                      
            scale = 1.0;

            p = 0.5 * scale;
            n = -0.5 * scale;
            
            vecFace  = Vector.<uint>([1, 0, 2, 1, 2, 3]);

            vecVert  = Vector.<Number>([
             n, n, 0.0,
             p, n, 0.0,
             n, p, 0.0,
             p, p, 0.0 ]);
             
            vecUv =  Vector.<Number>([
            0.0, 0.0,
            1.0, 0.0,
            0.0, 1.0,
            1.0, 1.0  ]);
            
    }//makesprite
    
    public function makeCube():void
    {
        vecFace = new Vector.<uint>;
        vecVert = new Vector.<Number>;
        vecUv = new Vector.<Number>;
        
        var n:Number;
        var p:Number;
        
        n = -0.5;
        p = 0.5;
        
        addQuad([n,n,n, 0,0],[p,n,n, 1,0],  [n,p,n, 0,1],        [p,p,n, 1,1]);      
        addQuad(        [n,n,p, 0,0],       [n,p,p, 1,0],        [p,n,p, 0,1],        [p,p,p, 1,1]);            
        addQuad(         [n,n,n, 0,0],        [n,n,p, 1,0],        [p,n,n, 0,1],        [p,n,p, 1,1]);       
        addQuad(         [n,p,n, 0,0],        [p,p,n, 1,0],        [n,p,p, 0,1],        [p,p,p, 1,1]);    
        addQuad(         [n,n,n, 0,0],        [n,p,n, 1,0],        [n,n,p, 0,1],        [n,p,p, 1,1]);       
        addQuad(         [p,n,n, 0,0],        [p,n,p, 1,0],        [p,p,n, 0,1],        [p,p,p, 1,1]);
                
    }//makecube
    
    
    public function addTri(v1:Array, v2:Array, v3:Array):void
    {
        if (v1.length < 5) { return; }
        if (v2.length < 5) { return; }
        if (v3.length < 5) { return; }
        
       // var numFace:int;
       // numFace = vecFace.length;
        var numVert:int;
        numVert = vecVert.length / 3;
        
        
       vecVert.push(v1[0]); vecVert.push(v1[1]); vecVert.push(v1[2]);
       vecUv.push(v1[3]); vecUv.push(v1[4]);
     
       vecVert.push(v2[0]); vecVert.push(v2[1]); vecVert.push(v2[2]);
       vecUv.push(v2[3]); vecUv.push(v2[4]);
     
       vecVert.push(v3[0]); vecVert.push(v3[1]); vecVert.push(v3[2]);
       vecUv.push(v3[3]); vecUv.push(v3[4]);
        
       vecFace.push(numVert+0); vecFace.push(numVert+1); vecFace.push(numVert+2);
        
        
    }//addface
    
    public function addQuad(v1:Array, v2:Array, v3:Array, v4:Array):void
    {
        if (v1.length < 5) { return; }
        if (v2.length < 5) { return; }
        if (v3.length < 5) { return; }
        if (v4.length < 5) { return; }
        
        //var numFace:int;
        //numFace = vecFace.length;
        
        var numVert:int;
        numVert = vecVert.length / 3;
        
       vecVert.push(v1[0]); vecVert.push(v1[1]); vecVert.push(v1[2]);
       vecUv.push(v1[3]); vecUv.push(v1[4]);
     
       vecVert.push(v2[0]); vecVert.push(v2[1]); vecVert.push(v2[2]);
       vecUv.push(v2[3]); vecUv.push(v2[4]);
     
       vecVert.push(v3[0]); vecVert.push(v3[1]); vecVert.push(v3[2]);
       vecUv.push(v3[3]); vecUv.push(v3[4]);
       
       vecVert.push(v4[0]); vecVert.push(v4[1]); vecVert.push(v4[2]);
       vecUv.push(v4[3]); vecUv.push(v4[4]);
        
        
        
       vecFace.push(numVert+0); vecFace.push(numVert+1); vecFace.push(numVert+2);
       vecFace.push(numVert+1); vecFace.push(numVert+3); vecFace.push(numVert+2);
    }//addquad
    
    
    
    
    
};//classend