/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/QbXN
*/
package
{
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
/**
* ...
* @author ypc
*/
[SWF(width = 465, height = 465)]
public class Main extends Sprite
{
public var noiseBitmapData:BitmapData;
public var bitmapData:BitmapData;
public var heightMapData:BitmapData;
public var screenMapData:BitmapData;
public var seed:uint = 0;
public var noiseType:int = 3;
public var terrainColorDict:Array = [0x000080, 0x0000ff, 0x0080ff, 0xf0f040, 0x20a000, 0xe0e000, 0x808080, 0xffffff];
public var terrainColorNum:Array = [0, 0.125, 0.5, 0.53125, 0.5625, 0.6875, 0.875, 1];
public var _width:int = 220;
public var _height:int = 220;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
noiseBitmapData = new BitmapData(_width, _height, false, 0x0);
bitmapData = new BitmapData(_width, _height, false, 0x0);
heightMapData = new BitmapData(_width, _height, false, 0x0);
screenMapData = new BitmapData(_width, _height, true, 0x0);
var bitmap0:Bitmap;
bitmap0 = new Bitmap(noiseBitmapData);
addChild(bitmap0);
var bitmap:Bitmap;
bitmap = new Bitmap(bitmapData);
bitmap.x = _width;
addChild(bitmap);
var bitmap2:Bitmap;
bitmap2 = new Bitmap(heightMapData);
bitmap2.y = _height;
addChild(bitmap2);
var bitmap3:Bitmap;
bitmap3 = new Bitmap(screenMapData);
bitmap3.x = _width;
bitmap3.y = _height;
addChild(bitmap3);
var perlinButton:PushButton = new PushButton(this, 0, 440, "Perlin Noise", function(e:Event):void {
noiseType = 1;
ridgedPerlin();
});
perlinButton.width = 465 / 3;
perlinButton.height = 25;
var ridgedPerlinButton:PushButton = new PushButton(this, perlinButton.x + perlinButton.width, perlinButton.y, "Ridged Perlin", function(e:Event):void {
noiseType = 2;
ridgedPerlin();
});
ridgedPerlinButton.width = 465 / 3;
ridgedPerlinButton.height = 25;
var reverseRidgedPerlinButton:PushButton = new PushButton(this, ridgedPerlinButton.x + ridgedPerlinButton.width, ridgedPerlinButton.y, "Ridged Perlin (Reverse)", function(e:Event):void {
noiseType = 3;
ridgedPerlin();
});
reverseRidgedPerlinButton.width = 465 / 3;
reverseRidgedPerlinButton.height = 25;
ridgedPerlin();
stage.addEventListener(MouseEvent.CLICK, ridgedPerlin);
}
public function ridgedPerlin(e:Event = null):void
{
seed = Math.random() * uint.MAX_VALUE;
noiseBitmapData.perlinNoise(_width / 2.0, _height / 2.0, 7, seed, false, true, 7, true);
var i:int;
var j:int;
var k:int;
var t:Number;
var num:Number;
var color:uint;
for (i = 0; i < _width; i += 1)
{
for (j = 0; j < _height; j += 1)
{
color = noiseBitmapData.getPixel(i, j);
color = color & 0xff;
num = color / 255.0;
if (noiseType > 1)
{
num *= 2;
num -= 1;
num = Math.abs(num);
num = 1 - num;
num *= num * num * num;
if (noiseType == 3)
{
num = 1 - num;
}
}
color = num * 255;
noiseBitmapData.setPixel(i, j, color << 16 | color << 8 | color);
}
}
for (i = 0; i < _width; i += 1)
{
for (j = 0; j < _height; j += 1)
{
color = noiseBitmapData.getPixel(i, j);
color = color & 0xff;
num = color / 255.0;
for (k = 0; k < terrainColorNum.length - 1; k += 1)
{
if (terrainColorNum[k] <= num && terrainColorNum[k+1] >= num)
{
t = (num - terrainColorNum[k]) / (terrainColorNum[k + 1] - terrainColorNum[k]);
color = interpolateColor(terrainColorDict[k], terrainColorDict[k + 1], t);
}
}
bitmapData.setPixel(i, j, color);
}
}
var slx:Number;
var sly:Number;
var sl0:Number;
var top:Number;
var bottom:Number;
var left:Number;
var right:Number;
var phi:Number;
var azimuth:Number;
var sunElev:Number = Math.PI * .25;
var sunAzimuth:Number = 1.75 * Math.PI;
var L:Number;
for (i = 0; i < _width; i += 1)
{
for (j = 0; j < _height; j += 1)
{
//slope
top = bitmapData.getPixel(i, Math.max(j - 1, 0)) & 0xff;
left = bitmapData.getPixel(Math.max(i - 1, 0), j) & 0xff;
right = bitmapData.getPixel(Math.min(i + 1, _width - 1), j) & 0xff;
bottom = bitmapData.getPixel(i, Math.min(j + 1, height - 1)) & 0xff;
slx = (right - left) / 2.0;
sly = (bottom - top) / 2.0;
sl0 = Math.sqrt(slx * slx + sly * sly);
//aspect
phi = Math.acos(slx / sl0);
if (sl0 == 0)
{
phi = 0;
}
if (slx > 0)
{
if (sly > 0)
{
azimuth = phi + 1.5 * Math.PI;
}
else if (sly < 0)
{
azimuth = 1.5 * Math.PI - phi;
}
else
{
phi = 1.5 * Math.PI;
}
}
else if (slx < 0)
{
if (sly < 0)
{
azimuth = phi + .5 * Math.PI;
}
else if (sly > 0)
{
azimuth = .5 * Math.PI - phi;
}
else
{
azimuth = .5 * Math.PI;
}
}
else
{
if (sly < 0)
{
azimuth = Math.PI;
}
else if (sly > 0)
{
azimuth = 0;
}
}
//reflectance
L = Math.cos(azimuth - sunAzimuth) * Math.cos(Math.PI * .5 - Math.atan(sl0)) * Math.cos(sunElev) + Math.sin(Math.PI * .5 - Math.atan(sl0)) * Math.sin(sunElev);
color = 255 * L;
if (color < 0)
{
color = 0;
}
if (color > 255)
{
color = 255;
}
heightMapData.setPixel(i, j, color << 16 | color << 8 | color);
}
}
screenMapData.fillRect(screenMapData.rect, 0x00ffffff);
screenMapData.draw(bitmapData);
var alphaColT:ColorTransform = new ColorTransform(1, 1, 1, 0.1, 0, 0, 0, 0);
//screenMapData.draw(heightMapData, null, alphaColT, "overlay");
screenMapData.draw(heightMapData, null, alphaColT, "add");
}
public static function interpolateColor(fromColor:uint, toColor:uint, progress:Number):uint
{
var q:Number = 1-progress;
var fromR:uint = (fromColor >> 16) & 0xFF;
var fromG:uint = (fromColor >> 8) & 0xFF;
var fromB:uint = fromColor & 0xFF;
var toR:uint = (toColor >> 16) & 0xFF;
var toG:uint = (toColor >> 8) & 0xFF;
var toB:uint = toColor & 0xFF;
var resultR:uint = fromR*q + toR*progress;
var resultG:uint = fromG*q + toG*progress;
var resultB:uint = fromB*q + toB*progress;
var resultColor:uint = resultR << 16 | resultG << 8 | resultB;
return resultColor;
}
}
}