flash on 2014-12-13
/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1UtX
*/
package {
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.text.TextField;
import flash.display.BitmapData;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
stage.quality = "LOW";
deb = new TextField(); deb.width =320; deb.height=240;
deb.mouseEnabled=false; addChild(deb);
var dat:BitmapData;
dat = new BitmapData(128,128, false, 0);
dat.perlinNoise(31,32, 14,15, true,true,7,true);
map =dat;
myHeight = new xHeightMap();
myHeight.cw=32; myHeight.ch=32;
myHeight.initHeight(dat, 3, -128);
// myHeight.cx = myHeight.mw*myHeight.cw * -0.5;
//myHeight.cz = myHeight.mh*myHeight.ch * -0.5;
//myHeight.initMap(8,8,0,0);
//myHeight.initMap(8,8,1,1);
myHeight.setTri(0,0,16,16);
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public var map:BitmapData;
public var temp:Matrix3D = new Matrix3D();
public var gt:int = 0;
public var cx:Number = 0;
public var cy:Number = 0;
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2, 0);
var ax:Number; var ay:Number;
var mx:Number; var my:Number;
mx = stage.mouseX; my = stage.mouseY;
ax = mx; ay= my;
if (ax <0){ax=0;} if (ay <0){ay=0;}
if (ax > 128) {ax=128;} if (ay>128){ay=128;}
cx = (myHeight.mw/128)*ax;
cy = (myHeight.mh/128)*ay;
if (cx>=myHeight.mw-16){cx=myHeight.mw-16;}
if (cy>=myHeight.mh-16){cy=myHeight.mh-16;}
graphics.beginFill(0x404040,1);
graphics.drawRect(0,0,465,465);
graphics.endFill();
graphics.beginBitmapFill(map,null,false,false);
graphics.drawRect(0,0, 128, 128);
graphics.endFill();
// ax = cx / myHeight.mw; ay = cy/myHeight.mh;
graphics.drawCircle(ax,ay, 4);
gt += 1;
deb.text = ""+gt+"\n"+myHeight.nface;
//if ((gt % 4) == 0) { cx += 1; }
// if (cx >= myHeight.mw) { cx = 0; }
var h:Number;
h = myHeight.getHeight(cx*32+256,cy*32+256);
temp.identity();
// temp.appendTranslation(-gt-64, 0, -gt-64);
//temp.appendTranslation(-cx * myHeight.cw-128, -128,0);
temp.appendTranslation(-cx * myHeight.cw-320-128, -h-128,-cy*myHeight.ch-128-32);
temp.appendRotation(70, Vector3D.Y_AXIS);
temp.appendRotation(-45, Vector3D.X_AXIS);
myMat = temp.rawData;
// myHeight.setTri(gt/myHeight.cw, gt/myHeight.ch,16,16);
myHeight.setTri(cx, cy, 16,16);
graphics.lineStyle(1, 0);
drawMesh(myHeight.nface*3, myHeight.vecFace, myHeight.vecVert, myMat);
drawSprite(cx*32+256,0, cy*32+256, 8, myMat);
drawSprite(cx*32+256,h, cy*32+256, 8, myMat);
// drawSprite(256,0, 256, 32, myMat);
var i:int; var k:int;
for (i =0 ;i<16; i++)
for (k = 0; k <16; k++)
{
ax = k*256;ay=i*256;
h = myHeight.getHeight(ax, ay);
drawSprite(ax, h, ay, 16, myMat, 0x808080);
}//nexti
}//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(num:int, 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;
var c:uint;
//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; }
if (ry > 256) {c = 0x80; } else
if (ry > 128) { c = 0xFF;} else
if (ry < 64) { c= 0x008000; }
else { c= 0xA0A000;}
graphics.beginFill(c, 1.0);
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;
internal class xHeightMap
{
public var vecHeight:Vector.<Number>;
public var vecVert:Vector.<Number>;
public var vecFace:Vector.<int>;
public var nface:int = 0;
//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
vmw = w; vmh = h;
mw = w-1; mh = h-1;
vecVert = new Vector.<Number>(4096*12,false);
vecFace = new Vector.<int>(4096*3, false);
num = vecFace.length; k = 0;
for (i = 0; i < num; i+=6)
{
vecFace[i] = 0+k; vecFace[i+1] = 1+k; vecFace[i+2] = 2+k;
vecFace[i+3] = 2+k; vecFace[i+4] = 1+k; vecFace[i+5] = 3+k;
k += 4;
}//nexti
}//initheight
public function setTri(x0:int, y0:int, w0:int, h0:int):void
{
var i:int; var k:int; var yt:int;
var ek:int; var ei:int; var sk:int; var si:int;
var v:int; var h:Number;
sk = x0; si = y0;
ek = x0+w0; ei = y0+h0;
if (sk > (mw-1)) { return; } if (si > (mh-1)) { return; }
if (ek < 1) { return; } if (ei < 1) { return; }
if (sk < 0) { sk = 0; } if (si < 0) { si = 0; }
if (ek > (mw-1)) { ek = mw-1;} if (ei > (mh-1)) { ei = mh-1;}
nface = 0;
var maxv:int; maxv = vecVert.length;
v = 0;
for (i = si; i < ei; i++)
{
yt = i * vmw;
for (k = sk; k < ek; k++)
{
h = vecHeight[yt+k];
vecVert[v] = k*cw + cx; vecVert[v+1] = h; vecVert[v+2] = i*ch+cz;
v += 3;
h = vecHeight[yt+k+vmw];
vecVert[v] = k*cw + cx; vecVert[v+1] = h; vecVert[v+2] = i*ch+cz+ch;
v += 3;
h = vecHeight[yt+k+1];
vecVert[v] = k*cw + cx+cw; vecVert[v+1] = h; vecVert[v+2] = i*ch+cz;
v += 3;
h = vecHeight[yt+k+1+vmw];
vecVert[v] = k*cw + cx+cw; vecVert[v+1] = h; vecVert[v+2] = i*ch+cz+ch;
v += 3;
nface+=2;
if (v >= maxv) { return; }
}//nextk
}//nexti
}//setbuf
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