3D Perlin
/**
* Copyright k3lab ( http://wonderfl.net/user/k3lab )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/sDvw
*/
package {
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import net.hires.debug.Stats;
[SWF(width="465", height="465", frameRate="30",backgroundColor = "0x0")]
public class Main extends Sprite {
//
private const PARTICLENUM:int=5000;
private const DISTANCE:int = 100;
private const VIEWANGLE:int = 200;
private const SIZE:int = 465;
//
private var _mx:Number = 0;
private var _my:Number = 0;
private var _canvas:BitmapData;
private var _bmpPerlin:BitmapData;
private var _buffer:BitmapData;
private var _pArray:Array=[];
private var _mouseDown:Boolean;
//
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
_bmpPerlin = new BitmapData(SIZE, SIZE, false, 0);
_canvas = new BitmapData(SIZE, SIZE, true, 0);
_buffer = new BitmapData(SIZE, SIZE, true, 0);
addChild(new Bitmap(_canvas))
randomPerlin();
createParticle();
stage.addEventListener(MouseEvent.MOUSE_DOWN, down);
stage.addEventListener(MouseEvent.MOUSE_UP, up);
addEventListener(Event.ENTER_FRAME, loop);
addChild(new Stats());
}
//********************************************************
private function up(e:MouseEvent):void {
_mouseDown = false;
}
private function down(e:MouseEvent):void {
_mouseDown = true;
randomPerlin();
}
private function randomPerlin():void {
_bmpPerlin.perlinNoise(100, 100, 3, Math.round(Math.random() * 100), false, true);
}
//********************************************************
private function createParticle():void{
var i:int;
while (i < PARTICLENUM) {
var rand:Number = Math.random() * DISTANCE;
var p:Particle = new Particle(0, 0, rand, Math.random() * 0xFF);
p.cx = p.cy =235;
p.d = DISTANCE;
_pArray.push(p);
i++;
}
}
//********************************************************
private function rotate(tx:Number, ty:Number):void {
var length:int = _pArray.length;
while (--length > -1) {
var p:Particle = _pArray[length];
var xp:Number = p.px * Math.cos(0) - p.py * Math.sin(0);
var yp:Number = p.py * Math.cos(0) + p.px * Math.sin(0);
var zp:Number = p.pz * Math.cos(ty) + xp * Math.sin(ty);
var ax:Number = xp * Math.cos(ty) - p.pz * Math.sin(ty);
var ay:Number = yp * Math.cos(tx) - zp * Math.sin(tx);
var az:Number = zp * Math.cos(tx) + yp * Math.sin(tx);
p.x = ax;
p.y = ay;
p.z = az;
}
}
//********************************************************
private function loop(e:Event):void{
if (_mx < -Math.PI){
_mx += Math.PI * 2;
}else {
if (_mx > Math.PI) _mx -= Math.PI * 2;
}
if (_my < -Math.PI){
_my += Math.PI * 2;
}else {
if (_my > Math.PI) _my -= Math.PI * 2;
}
if (_mouseDown){
_mx += (mouseX - 235) * 0.001;
_my -= (mouseY - 235) * 0.001;
}else {
_mx *= 0.95;
_my *= 0.95;
}
//
rotate(_my, _mx);
//
_buffer.lock();
_buffer.colorTransform(_buffer.rect, new ColorTransform(1, 1, 1, 1, 0, 0, 0, -5));
_buffer.applyFilter(_buffer, _buffer.rect, new Point(), new BlurFilter(3, 3, 1));
var length:int = _pArray.length;
while (--length > -1) {
var p:Particle = _pArray[length];
if (p.z > -DISTANCE){
var vp:Number = VIEWANGLE / (VIEWANGLE + p.z + DISTANCE);
var xPos:Number = int(p.x * vp + 0.5) + 235;
var yPos:Number = int(p.y * vp + 0.5) + 235;
_buffer.setPixel32(xPos, yPos, p.c);
}
p.update(_bmpPerlin.getPixel(p.px + 235, p.py + 235));
}
_canvas.copyPixels(_buffer, _buffer.rect, new Point());
_buffer.unlock();
}
}
}
class Particle {
public var x:Number;
public var y:Number;
public var z:Number;
public var px:Number;
public var py:Number;
public var pz:Number;
public var vx:Number;
public var vy:Number;
public var c:uint;
public var d:int;
public var cx:int;
public var cy:int;
public function Particle(px:Number,py:Number,pz:Number,c:uint):void {
this.px = px;
this.py = py;
this.pz = pz;
vx = Math.random() - Math.random() * 5;
vy = Math.random() - Math.random() * 5;
this.c = c;
}
public function update(value:uint):void {
var r:Number = value >> 16;
var g:Number = value >> 8 & 0xFF;
var b:Number = value & 0xFF;
var a:Number = (Math.max(Math.max(r, g), b) / 0xFF * d * 2 ) - d;
vx += (r - b) / 100;
vy += (g - b) / 100;
vx = Math.min(vx, 5);
vy = Math.min(vy, 5);
vx = Math.max(vx, -5);
vy = Math.max(vy, -5);
px += vx;
py += vy;
pz += (a - pz) * 0.5;
if (px < -cx || px > cx) vx *= -1;
if (py < -cy || py > cy) vy *= -1;
r = (px + cx) / (cx * 2) * 0xFF;
g = (py + cy) / (cy * 2) * 0xFF;
b = Math.abs(Math.round(vx + vy)) * 10;
c = 0xFF << 24 | r << 16 | g << 8 | b
}
}