forked from: 250000 particle flow shimulation
なんかいっぱい動かすテスト
洗濯機みたいになってます。
@author jc at bk-zen.com
// forked from fladdict's 250000 particle flow shimulation
// forked from fladdict's 20万個ぱーてぃくる 途中で飽きたけど 25万個は狙えるはず
// forked from beinteractive's forked from: 10万個ぱーてぃくる - 軽く高速化
// forked from bkzen's 10万個ぱーてぃくる
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import net.hires.debug.Stats;
/**
* なんかいっぱい動かすテスト
* 洗濯機みたいになってます。
* @author jc at bk-zen.com
*/
[SWF(backgroundColor = "0x000000", frameRate = "30")]
public class Test3 extends Sprite
{
private var main: TestMain;
public function Test3()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//
main = new TestMain(stage.stageWidth, stage.stageHeight);
addChild(main.view);
addChild(new Stats());
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE, onResize);
stage.addEventListener(MouseEvent.CLICK, onClick);
addEventListener(Event.ENTER_FRAME, onEnter);
}
private function onClick(e:MouseEvent):void
{
main.change();
}
private function onEnter(e:Event):void
{
main.draw(mouseX, mouseY);
}
// りサイズ (未実装)
private function onResize(e:Event):void
{
main.resize(stage.stageWidth, stage.stageHeight);
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.utils.ByteArray;
import flash.display.Shader;
import flash.display.ShaderJob;
class TestMain
{
protected const W: int = 300;
protected const H: int = 300;
protected const N: int = W*H;
private var w: int;
private var h: int;
private var mw: int;
private var mh: int;
public var view: Bitmap;
private var bmpData: BitmapData;
private var forceMap: BitmapData;
private var forceCache: Array;
private var randomSeed: int;
// private var particles: Particle;
private var _pxv : Vector.<Number>;
private var _pc : Vector.<uint>;
private var num: int;
private var color: uint = 0xF0F0FF;
private var count: int = 0;
private var colorTr: ColorTransform;
private var cnt:int = 0;
//forcemap を getPixel で計算すると重いので、色はキャッシュする。
private var forceVector:Vector.<int>;
private var fxVector:Vector.<int>;
private var fyVector:Vector.<int>;
private var _shader : Shader;
public function TestMain(w: int, h: int)
{
this.w = w;
mw = w >> 1;
this.h = h;
mh = h >> 1;
bmpData = new BitmapData(w, h, false, 0x00000000);
forceMap = new BitmapData(w, h, false);
view = new Bitmap(bmpData);
var i: int;
_pxv = new Vector.<Number>();
_pc = new Vector.<uint>();
for(i = 0;i < N;i++){
_pxv.push(
Math.random() * w, Math.random() * h,
0.0, 0.0);
_pc.push(
Math.random() * 0xffffff);
}
colorTr = new ColorTransform(1, 1, 1, 1, -90, -90, -90);
change();
_shader = new MegaParticleShader();
_res = new Vector.<Number>();
_shader.data.xv.width = W;
_shader.data.xv.height = H;
_shader.data.mu.value = [0.99];
_shader.data.w.value = [465.0];
_shader.data.h.value = [465.0];
_shader.data.force.input = forceMap;
}
private var _res : Vector.<Number>;
// 描画、マウスの判定を後で追加予定
public function draw(mouseX: Number, mouseY: Number): void
{
cnt++;
if(cnt>100){
change();
cnt = 0;
}
var col: uint;
var forceIndex:int;
bmpData.lock();
bmpData.colorTransform(bmpData.rect, colorTr);
_shader.data.xv.input = _pxv;
var sj : ShaderJob = new ShaderJob(_shader, _res, W, H);
sj.start(true);
_pxv = _res;
for(var i : int = (_pxv.length>>2)-1;i >= 0;--i){
bmpData.setPixel(_pxv[i<<2], _pxv[(i<<2)+1], _pc[i]);
}
/*
while ((p = p.next) != null)
{
forceIndex = (p.y>>2) * mw + (p.x>>2);
//2万個以上はパーティクルの座標が重なった場合の対策をしないと、
//まったく同じ動きをするので意味がないので p.rndに乱数を持たせて、力に揺らぎを与える。
p.vx = p.vx * 0.99 + fxVector[forceIndex] * p.rnd;
p.vy = p.vy * 0.99 + fyVector[forceIndex] * p.rnd;
p.x += p.vx;
p.y += p.vy;
if (p.x < 0) p.x += w;
else if (p.x >= w) p.x -= w;
if (p.y < 0) p.y += h;
else if (p.y >= h) p.y -= h;
bmpData.setPixel(int(p.x), int(p.y), p.col);
}
*/
bmpData.unlock();
}
public function change(): void
{
/**
この処理は重いので、本当は次のforcemapの生成をバックグラウンドで少しづつ行って、完成したら切り替えるようにする。
*/
forceMap.perlinNoise(128, 128, 8, Math.random() * 0xFFFF, false, true, 7, false);
/*
if(!forceVector){
fxVector = new Vector.<int>(mw*mh,true);
fyVector = new Vector.<int>(mw*mh,true);
}
//force mapをキャッシュする
for(var yy:int=0; yy<mh; yy++){
for(var xx:int=0; xx<mw; xx++){
var col:int = forceMap.getPixel(xx,yy);
var pos:int = yy*mw+xx;
fxVector[pos] = (col>>16&0xff)-128;
fyVector[pos] = (col>>8&0xff)-128;
}
}
*/
}
public function resize(w: Number, h: Number): void
{
this.w = w;
this.h = h;
if (bmpData)
{
bmpData.dispose();
}
bmpData = new BitmapData(w, h, false, 0x00000000);
view.bitmapData = bmpData;
}
}
class Particle
{
public var x: Number = 0;
public var y: Number = 0;
public var vx: Number = 0;
public var vy: Number = 0;
public var rnd: Number = 0;
public var col:int= Math.random()*256*256*256;
public var next: Particle;
public function Particle()
{
}
}
import flash.display.Shader;
import flash.utils.ByteArray;
class MegaParticleShader extends Shader
{
private var vec:Vector.<int> = Vector.<int>( [ 117,144,187,78,2,65,24,133,207,220,12,197,38,110,111,54,177,214,70,136,218,88,184,9,182,70,43,91,153,176,131,146,0,75,246,130,54,38,243,30,54,32,104,205,35,192,219,88,74,120,1,255,217,93,131,18,220,98,79,230,156,243,127,115,121,103,0,102,30,174,205,131,190,213,73,214,109,247,204,216,27,232,190,73,135,186,109,254,248,24,123,35,51,136,226,4,24,215,70,38,73,187,241,0,140,220,200,164,237,164,59,204,220,26,19,198,1,239,254,38,207,154,113,156,68,152,66,62,143,48,101,178,19,39,4,156,112,201,176,31,165,25,21,105,111,222,207,241,198,34,211,209,121,47,187,211,189,220,224,242,101,56,43,50,246,180,29,53,63,173,27,227,168,61,238,138,234,2,43,192,71,32,177,22,56,64,192,161,37,230,8,4,150,146,252,6,135,31,90,64,10,212,57,190,32,132,27,241,113,162,176,18,152,179,96,15,107,229,230,138,188,85,228,116,87,52,20,108,147,222,137,52,116,26,40,212,247,40,231,164,170,226,94,92,189,126,144,191,84,180,159,32,117,124,215,35,46,88,213,115,231,113,57,19,46,111,21,115,132,195,145,128,229,88,32,96,214,130,206,119,74,30,35,165,30,253,23,56,67,249,29,211,229,132,219,159,217,112,211,11,193,171,222,121,213,251,209,95,252,240,31,62,249,216,240,57,44,89,187,248,69,111,155,79,247,179,162,212,176,152,83,56,228,165,250,132,34,78,249,158,223 ] );
private var byteArr:ByteArray;
public function MegaParticleShader():void
{
var len:int = vec.length;
if(!byteArr)
{
byteArr = new ByteArray();
for(var i:int=0; i<len; i++)
{
byteArr.writeByte( vec[i] );
}
byteArr.inflate();
this.byteCode = byteArr;
}
}
}