flash on 2011-3-28
/**
* Copyright yonatan ( http://wonderfl.net/user/yonatan )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1qZN
*/
package {
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
import flash.utils.*;
import net.hires.debug.Stats;
[SWF (backgroundColor=0x808080)]
public class Grid extends Sprite {
private const W:int = 465;
private const H:int = 465;
private const wDiv:int = 50;
private const hDiv:int = 25;
private var nearScale:Number = 0.25;
private var noise:BitmapData = new BitmapData(W, H, false, 0);
private var heightMap:BitmapData = new BitmapData(W, H, false, 0);
private var heightMapShape:Shape = new Shape;
private var projectedHeightMap:BitmapData = new BitmapData(W, int(H/2), false, 0);
private var scaledHeightMap:BitmapData = new BitmapData(wDiv+1, hDiv+1, false, 0);
private var scaleDown:Matrix = new Matrix;
private var hmVertices:Vector.<Number> = new Vector.<Number>;
private var hmUvt:Vector.<Number> = new Vector.<Number>;
private var hmIndices:Vector.<int> = new Vector.<int>;
private var vertices:Vector.<Number> = new Vector.<Number>((wDiv+1) * (hDiv+1) * 2, true);
private var uvt:Vector.<Number> = new Vector.<Number>((wDiv+1) * (hDiv+1) * 3, true);
private var indices:Vector.<int> = new Vector.<int>(wDiv * hDiv * 6, true);
private var mtx:Matrix = new Matrix;
public function Grid() {
stage.quality = "medium";
stage.frameRate = 60;
hmVertices.push(0, 0, W, 0, 0, H/2, W, H/2);
hmIndices.push(0, 1, 2, 2, 1, 3);
initGrid();
noise.perlinNoise(W, H, 7, 3, true, false, 7, true);
noise.colorTransform(heightMap.rect, new ColorTransform(5,4,3));
scaleDown.scale((wDiv+1)/W, (hDiv+1)/H*2);
addEventListener("enterFrame", frame);
var bmp:Bitmap = new Bitmap(projectedHeightMap);
bmp.scaleX = bmp.scaleY = 0.33;
bmp.x = 80;
addChild(bmp);
bmp = new Bitmap(scaledHeightMap);
bmp.width = 200;
bmp.height = 100;
bmp.x = 250;
addChild(bmp);
addChild(new Stats);
}
private var cnt:int = 0;
private function frame(e:*):void {
heightMap.copyPixels(noise, noise.rect, noise.rect.topLeft);
mtx.identity();
mtx.rotate(getTimer()/15000);
mtx.translate(0, getTimer()/10000);
project();
updateGrid();
}
private function project():void {
hmUvt.length = 0;
hmUvt.push(
-0.5, 1, nearScale,
0.5, 1, nearScale,
-nearScale/2, 0, 1,
nearScale/2, 0, 1);
var ui:int = 0;
var len:int = hmUvt.length;
while(ui < len) {
var p:Point = new Point();
p.x = hmUvt[ui];
p.y = hmUvt[ui+1];
p = mtx.transformPoint(p);
hmUvt[ui++] = p.x;
hmUvt[ui++] = p.y;
ui++;
}
heightMapShape.graphics.clear();
heightMapShape.graphics.beginBitmapFill(heightMap, null, true);
heightMapShape.graphics.drawTriangles(hmVertices, hmIndices, hmUvt);
heightMapShape.graphics.endFill();
projectedHeightMap.fillRect(projectedHeightMap.rect, 0);
projectedHeightMap.draw(heightMapShape);
}
private function initGrid():void {
var ui:int = 0;
var ii:int = 0;
for(var i:int = 0; i <= hDiv; i++) {
for(var j:int = 0; j <= wDiv; j++) {
var x:Number = j / wDiv * (W-2);
var y:Number = i / hDiv * (H/2-1);
var z:Number = i/(hDiv+1); // FIXME?
uvt[ui++] = j/(wDiv+1);
uvt[ui++] = z;
uvt[ui++] = z;
if (j < wDiv && i < hDiv) {
var a:uint = i * (wDiv+1) + j;
var b:uint = (i + 1) * (wDiv+1) + j;
indices[ii++] = b;
indices[ii++] = a + 1;
indices[ii++] = a;
indices[ii++] = a + 1;
indices[ii++] = b;
indices[ii++] = b + 1;
}
}
}
}
private function updateGrid():void {
var vi:int = 0;
scaledHeightMap.fillRect(scaledHeightMap.rect, 0);
scaledHeightMap.draw(projectedHeightMap, scaleDown, null, null, null, true);
for(var i:int = 0; i <= hDiv; i++) {
for(var j:int = 0; j <= wDiv; j++) {
var x:Number = j / wDiv * (W-2);
var y:Number = i / hDiv * (H/2-1);
var height:Number = (scaledHeightMap.getPixel(j, i) & 0xFF) / 0xFF * 2 - 1; // between -1 and 1
vertices[vi++] = x;
vertices[vi++] = H/2 - height * y;
}
}
graphics.clear();
// graphics.lineStyle(1, 0x004488);
graphics.beginBitmapFill(projectedHeightMap);
graphics.drawTriangles(vertices, indices, uvt);//, "positive");
graphics.endFill();
}
}
}