life of Microorganism
Dropwaterデバッグ中にできたエフェクトから派生。あいかわらずむちゃくちゃ重いです。もともとは生態シミュレータ的なものに
したかったんですが、いまいちなので寝かせていました。Dropwaterを無理無理改造しているのでソースは汚いです。
曲はAlainMikuni氏(from gainaさんのsoundtest11 http://wonderfl.net/c/bB5h)からお借りしています。
ありがとうございます。
※操作できません。微生物?の動きを眺めてください
2010/9/28 微調整
2010/9/29 さらに微調整。顕微鏡感を増してみた
/**
* Copyright zendenmushi ( http://wonderfl.net/user/zendenmushi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oUra
*/
// << life of Microorganism >>
//
// Dropwaterデバッグ中にできたエフェクトから派生。あいかわらずむちゃくちゃ重いです。もともとは生態シミュレータ的なものに
// したかったんですが、いまいちなので寝かせていました。Dropwaterを無理無理改造しているのでソースは汚いです。
//
// 曲はAlainMikuni氏(from gainaさんのsoundtest11 http://wonderfl.net/c/bB5h)からお借りしています。
// ありがとうございます。
//
// ※操作できません。微生物?の動きを眺めてください
package
{
import com.bit101.components.CheckBox;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageDisplayState;
import flash.events.Event;
import flash.events.FullScreenEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.filters.DropShadowFilter;
import flash.filters.ShaderFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundLoaderContext;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.system.Security;
import flash.utils.ByteArray;
import flash.utils.getTimer;
/**
* ...
* @author TM
*/
[SWF(width=465,height=465,backgroundColor=0,frameRate=30)]
public class soundSpectrumMetaRGB extends Sprite
{
private var snd:Sound;
private var FFTswitch:Boolean = false;
private var body_canvas : BitmapData; //worm 一体分を描画するcanvas
private var canvas : BitmapData;
private var canvasBmp : Bitmap;
private var food : BitmapData;
private var cylinder : Sprite = new Sprite();
private var zeroPoint : Point = new Point(0, 0);
private var dropimages : Vector.<MetaCircle> = new Vector.<MetaCircle>;
private var uiBar : Sprite = new Sprite();
private var tempPos : Point = new Point();
private var tempRect : Rectangle = new Rectangle();
private var metaEffect : MetaEffectPB = new MetaEffectPB();
private var metaEffectFilter : ShaderFilter = new ShaderFilter(metaEffect);
private var debugMode : Boolean = false;
private var solidlMode : Boolean = false;
private var shiftKeyIsDown : Boolean = false;
private var mouseIsDown : Boolean = false;
private var downPoint : Point = new Point();
private var captureDrop : InvisibleWorm = null;
private var captureRadius : Number = 0;
private var fullscreenCheckbox : CheckBox;
private var drops : Vector.<InvisibleWorm> = new Vector.<InvisibleWorm>;
private var freep : int = -1;
private const itemlimit : int = 30;
public function soundSpectrumMetaRGB()
{
Wonderfl.capture_delay( 30 );
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.ENTER_FRAME, enterFrame);
stage.addEventListener(MouseEvent.CLICK, mouseClick);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, changeFullscreen);
stage.doubleClickEnabled = true;
WIDTH = stage.stageWidth;
HEIGHT = stage.stageHeight;
graphics.clear();
graphics.beginFill(0xcedefa);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
food = new BitmapData(WIDTH, HEIGHT, true, 0);
food.noise(getTimer(), 0, 16, 15, true);
addChild(new Bitmap(food));
canvas = new BitmapData(WIDTH,HEIGHT, true, 0xff000000);
canvasBmp = new Bitmap(canvas);
addChild(canvasBmp);
canvasBmp.filters = [ new DropShadowFilter(1, Math.PI/2, 0x404060, 0.5) ];
body_canvas = canvas.clone();
cylinder.graphics.clear();
cylinder.graphics.beginFill(0, 0.8);
cylinder.graphics.drawRect(-16, -16, stage.stageWidth+16*2, stage.stageHeight+16*2);
cylinder.graphics.drawCircle(stage.stageWidth / 2, stage.stageHeight / 2, Math.max(stage.stageWidth, stage.stageHeight) *1.2 / 2);
cylinder.graphics.endFill();
cylinder.filters = [ new BlurFilter(16, 16) ];
addChild(cylinder);
addChild(uiBar);
uiBar.graphics.clear();
uiBar.graphics.beginFill(0, 0.7);
uiBar.graphics.drawRect(0, 0, stage.stageWidth, 16);
uiBar.graphics.endFill();
uiBar.y = stage.stageHeight - 16;
fullscreenCheckbox = new CheckBox( uiBar, 2, 2, "FULL SCREEN", fullscreenChecked);
for (var r : Number = 0; r <= MAX_RADIUS; r++) {
dropimages[r] = new MetaCircle(r + 1, r > 10 ? 1.0 : r / 20 +0.5 );
}
InvisibleWorm.metaImages = dropimages;
playSound("http://www.takasumi-nagai.com/soundfiles/sound004.mp3");
//Security.allowDomain("locadlhost");// playSound("sound001.mp3"); // for local test
}
private function changeFullscreen(e:Event):void
{
if (stage.displayState == StageDisplayState.FULL_SCREEN) {
fullscreenCheckbox.selected = true;
} else {
fullscreenCheckbox.selected = false;
}
}
private function fullscreenChecked(e:Event) : void
{
if (!fullscreenCheckbox.selected) {
stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
stage.displayState = StageDisplayState.NORMAL;
} else {
stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
stage.displayState = StageDisplayState.FULL_SCREEN;
}
}
private function playSound(sndUrl:String):void
{
snd = new Sound();
var context:SoundLoaderContext = new SoundLoaderContext(10,true);
var req:URLRequest = new URLRequest(sndUrl);
var sndChannel:SoundChannel=new SoundChannel();
snd.load(req, context);
sndChannel = snd.play(0, 9999);
}
private function mouseClick(e:MouseEvent):void
{
/* // pixelBender ToolKit用ソース画像取り込み
var pFile :FileReference = new FileReference();
var imageSnap:ImageSnapshot = ImageSnapshot.captureImage(canvasBmp);
// var imageSnap:ImageSnapshot = ImageSnapshot.captureImage(new Bitmap(dropimages[99].densityImage));
var imageByteArray:ByteArray = imageSnap.data as ByteArray;
pFile.save(imageByteArray, "image.png");
*/
}
private function mouseUp(e:MouseEvent):void
{
mouseIsDown = false;
captureDrop = null;
}
private function mouseDown(e:MouseEvent):void
{
mouseIsDown = true;
downPoint.x = e.stageX;
downPoint.y = e.stageY;
}
private function keyDown(e:KeyboardEvent):void
{
if (e.charCode == 122) { // "Z"
debugMode = !debugMode;
} else if (e.charCode == 120) { // "X"
}
shiftKeyIsDown = e.shiftKey;
}
private function keyUp(e:KeyboardEvent):void
{
shiftKeyIsDown = e.shiftKey;
}
private function newItem( x : Number, y : Number) : InvisibleWorm
{
var cnt : int = drops.length;
if (((itemlimit > 0) && cnt >= itemlimit) && (freep >= cnt-1)) return null;
freep++;
if (freep == cnt) {
drops[cnt] = new InvisibleWorm(x, y);
} else {
drops[freep].regenerate(x, y);
}
drops[freep].index = freep;
drops[freep].visible = true;
return drops[freep];
}
private function remove(index : int) : void
{
var cnt : int = drops.length;
var temp : InvisibleWorm = drops[index];
var lastp : int = freep;
temp.visible = false;
//removeChild(temp);
if (lastp != index) {
drops[index] = drops[lastp];
drops[index].index = index;
drops[lastp] = temp;
}
freep = lastp - 1;
}
private var new_interval : int = 0;
private function enterFrame(e:Event):void
{
var i : int, j : int, drop : InvisibleWorm;
var bytes:ByteArray = new ByteArray();
var lx : Number, ly : Number, change_light : Boolean = false;
SoundMixer.computeSpectrum(bytes, FFTswitch, 0);
new_interval ++;
var grow : Boolean = false;
for (i = 0; i < 2; i++)
{
for (j = 0; j < 256; j++)
{
drop = null;
var rf : Number = bytes.readFloat();
if (rf < 0) {
if ((new_interval >= 4) && (freep < itemlimit)) {
drop = newItem( stage.stageWidth / 2, stage.stageHeight / 2);
new_interval = 0;
}
//drop = newItem( (i < 1 ? j + 256 : 255 - j) * (stage.stageWidth / 512), (rf - 0.3) * 1000, rf * MAX_RADIUS);
}
var index : uint = 0;
if (rf < 0) {
index = (Math.random() * freep);
drop = drops[index];
drop.turn( -rf*50 );
}
if ((Math.abs(rf) > 0.1)) {
// index = int(i * j / 25.6) % 10;
index = (Math.random() * 10) >> 0;
if ((index < freep) && (index < 10)) {
drop = drops[index];
//if (rf > 0) drop.grow( rf * 80 ); else
drop.grow( rf * 1000 );
grow = true;
}
}
}
}
if (!grow) {
for (i = 0; (i < 10) && (i <= freep); i++) {
drop = drops[i];
drop.grow_target = 0;
}
}
var capture : Boolean = false;
var mindist : Number = 1000;
for (i = freep; i >= 0; i--) {
var dropA : InvisibleWorm = drops[i];
dropA.stepFrame();
if (dropA.age <= 5) remove(i);
}
if (!capture) {
captureDrop = null;
captureRadius = 0.0;
} else {
captureDrop.speed = mouseIsDown ? 0.0 : 0.3;
}
// canvas.copyPixels(food, food.rect, zeroPoint);
canvas.fillRect(canvas.rect, 0);
for (i = freep; i >= 0; i--) {
body_canvas.fillRect(body_canvas.rect, 0x000000);
drop = drops[i];
// render!
drop.draw( body_canvas , metaEffectFilter);
canvas.copyPixels(body_canvas, body_canvas.rect, zeroPoint, null, null, true);
}
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shader;
import flash.filters.ShaderFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
const MAX_RADIUS : Number = 50;
var WIDTH : int;
var HEIGHT : int;
class InvisibleWorm extends Bitmap
{
public static const IW_EGG : int = 0; // 卵
public static const IW_LARVAL : int = 1; // 幼生
public static const IW_METAMORPHOSE : int = 2; // 変態期
public static const IW_IMAGO_WORM : int = 3; // 成体-WORM型
public static const IW_IMAGO_AMEBA : int = 4; // 成体-アメーバ型
public static const IW_IMAGO_EEL : int = 5; // 成体-線虫型
public static var metaImages : Vector.<MetaCircle>;
public var index : int;
//public var visible : Boolean;
private var _radius : int;
//public var x : Number;
//public var y : Number;
private var tx : Number;
private var ty : Number;
public var dx : Number;
public var dy : Number;
private var angle : Number = 0;
public var fusion : Boolean;
public var age : uint = 0;
public var grow_target : uint = 0;
public var turn_next : Number = 0.0;
public var dead : Boolean = false;
public var lastSplit : Number;
public var befpos : Point = new Point();
public var state : int = 0;
public var speed : Number = 1.0;
public var speed_cnt : Number = 0.0;
public var lifeCycle : int = IW_EGG;
public var imagoType : int = IW_IMAGO_WORM;
private var track : Vector.<Point> = new Vector.<Point>;
private var track_top : int = 0;
private const TRACK_MASK : int = 0x1f;
//public var width : Number;
//public var height : Number;
private var color_typ : Array = [2.0, 2.0, 2.0];
private var color_offset : Array = [0.5, 0.5, 0.5];
private var tempPos : Point = new Point();
private var tempRect : Rectangle = new Rectangle();
private var zeroPoint : Point = new Point(0, 0);
public function InvisibleWorm(x : Number, y : Number)
{
for (var i : int = 0 ; i <= TRACK_MASK; i++) track[i] = new Point();
regenerate(x, y);
}
public function regenerate(x : Number, y : Number) : void
{
this.x = x;
this.y = y;
befpos.x = x;
befpos.y = y;
lastSplit = y;
tx = x;
ty = y;
this.dx = 0;
this.dy = 0;
radius = 10;
fusion = false;
visible = true;
age = 151;// Math.random() * 60;
grow_target = 0;
color_typ[0] = 2.0;
color_typ[1] = 2.0;
color_typ[2] = 2.0;
color_offset[0] = 0.5;
color_offset[1] = 0.5;
color_offset[2] = 0.5;
var imago_sai : Number = Math.random();
if (imago_sai < 0.3) {
imagoType = IW_IMAGO_WORM;
} else if (imago_sai < 0.6) {
color_typ[0] = 4.0;
color_typ[1] = 4.0;
color_typ[2] = 2.0;
color_offset[0] = 0.75;
color_offset[1] = 0.75;
color_offset[2] = 0.50;
imagoType = IW_IMAGO_AMEBA;
} else {
color_typ[0] = 5.0;
color_typ[1] = 5.0;
color_typ[2] = 5.0;
color_offset[0] = 0.80;
color_offset[1] = 0.80;
color_offset[2] = 0.80;
imagoType = IW_IMAGO_EEL;
}
state = Math.random()*60;
lifeCycle = IW_EGG;
for (var i : int = 0 ; i <= TRACK_MASK; i++) {
track[i].x = x;
track[i].y = y;
}
}
public function stepFrame() : void
{
if (speed <= 0.0) return;
speed += (1.0 - speed) / 4;
speed_cnt += speed;
if (speed_cnt < 1.0) return;
speed_cnt -= 1.0;
if (lifeCycle > IW_EGG) {
if (grow_target != 0) {
age += (grow_target - age) / 4;
if ( Math.abs(age - grow_target) <= 1.0 ) grow_target == 0;
}
if (grow_target == 0) {
if (lifeCycle == IW_LARVAL) age /= 1.005;
else age /= 1.05;
}
}
state++;
var rnd : Number, rad : Number;
if (!dead) {
radius = 5 + ((MAX_RADIUS - 5) / 1500) * age;
if (radius <= 0) radius = 0;
switch (lifeCycle) {
case IW_EGG: {
if (age > 150) {
lifeCycle = IW_LARVAL;
angle = Math.random() * Math.PI * 2;
dx = Math.cos(angle)*4;
dy = Math.sin(angle)*4;
} else {
dx = 0;
dy = 0;
}
break;
}
case IW_LARVAL: {
if (age > 1200) {
lifeCycle = IW_METAMORPHOSE;
state = 0;
} else {
var over : Boolean = false;
if (((tx < 0) || (tx > WIDTH)) && (tx * dx >= 0)) {
angle = Math.atan2( HEIGHT / 2 - ty, WIDTH / 2 - tx);
over = true;
}
if (((ty < 0) || (ty > HEIGHT)) && (ty * dy >= 0)) {
angle = Math.atan2( HEIGHT / 2 - ty, WIDTH / 2 - tx);
over = true;
}
if (((age % 10) == 0) || (turn_next > 0.0)) {
if (!over) {
rnd = Math.random() - 0.5;
if (turn_next > 0.0) rnd *= turn_next;
rad = rnd * Math.PI / 4;
angle += rad;
turn_next = 0.0;
}
}
dx = Math.cos(angle)*radius/4;
dy = Math.sin(angle)*radius/4;
}
break;
}
case IW_METAMORPHOSE: {
dx *= 0.5;
dy *= 0.5;
if (state > 120) {
radius *= 1.2;
lifeCycle = imagoType;
}
break;
}
case IW_IMAGO_WORM: {
over = false;
if ((tx < 0) || (tx > WIDTH)) {
if (tx * dx >= 0) {
angle -= Math.PI;
over = true;
}
}
if ((ty < 0) || (ty > HEIGHT)) {
if (ty * dy >= 0) {
angle -= Math.PI;
over = true;
}
}
if ((age % 10) == 0) {
if (!over) {
rnd = Math.random() - 0.5;
rad = (rnd) * Math.PI / 4;
angle += rad;
turn_next = 0.0;
}
}
dx = (Math.cos(angle)*0.7 + Math.cos(angle)*(Math.sin(state*Math.PI/30))*0.3)*radius/14;
dy = (Math.sin(angle)*0.7 + Math.sin(angle)*(Math.sin(state*Math.PI/30))*0.3)*radius/14;
break;
}
case IW_IMAGO_AMEBA: {
over = false;
if (((tx < 0) || (tx > WIDTH)) && (tx * dx >= 0)) {
angle -= Math.PI;
over = true;
}
if (((ty < 0) || (ty > HEIGHT)) && (ty * dy >= 0)) {
angle -= Math.PI;
over = true;
}
if (((age % 50) == 0) || (turn_next > 0.0)) {
if (!over) {
rnd = Math.random() - 0.5;
if (turn_next > 0.0) rnd *= turn_next;
rad = (rnd) * Math.PI / 2;
angle += rad;
turn_next = 0.0;
}
}
dx = (Math.cos(angle)*0.2 + Math.cos(angle)*(Math.sin(state*Math.PI/15))*0.8)*radius/32;
dy = (Math.sin(angle)*0.2 + Math.sin(angle)*(Math.sin(state*Math.PI/15))*0.8)*radius/32;
break;
}
case IW_IMAGO_EEL: {
over = false;
if (((tx < 0) || (tx > WIDTH)) && (tx * dx >= 0)) {
angle -= Math.PI;
over = true;
}
if (((ty < 0) || (ty > HEIGHT)) && (ty * dy >= 0)) {
angle -= Math.PI;
over = true;
}
if ((age % 20) == 0) {
if (!over) {
rnd = Math.random() - 0.5;
if (turn_next > 0.0) rnd *= turn_next*0.5;
rad = (rnd) * Math.PI;
angle += rad;
turn_next = 0.0;
}
}
dx = (Math.cos(angle)*0.6 + Math.cos(angle)*(Math.sin(state*Math.PI/15))*0.4)*radius/16;
dy = (Math.sin(angle)*0.6 + Math.sin(angle)*(Math.sin(state*Math.PI/15))*0.4)*radius/16;
break;
}
}
} else {
dx *= 0.99;
dy *= 0.99;
}
tx += dx;
ty += dy;
x += (tx - x) / 4;
y += (ty - y) / 4;
var befdx : Number, befdy : Number, movdist : Number;
switch (lifeCycle) {
case IW_EGG: {
break;
}
case IW_LARVAL: {
befdx = x - befpos.x;
befdy = y - befpos.y;
movdist = Math.sqrt(befdx * befdx + befdy * befdy);
if (movdist > radius / 2) {
befpos.x = x - (radius / 2) * befdx / movdist;
befpos.y = y - (radius / 2) * befdy / movdist;
}
befpos.x = track[ (track_top-2 ) & TRACK_MASK ].x;
befpos.y = track[ (track_top-2 ) & TRACK_MASK ].y;
break;
}
case IW_METAMORPHOSE: {
befpos.x += (x - befpos.x) / 8;
befpos.y += (y - befpos.y) / 8;
break;
}
case IW_IMAGO_WORM: {
var nextx : Number = track[ (track_top-8 ) & TRACK_MASK ].x;
var nexty : Number = track[ (track_top-8 ) & TRACK_MASK ].y;
befdx = x - nextx;
befdy = y - nexty;
movdist = Math.sqrt(befdx * befdx + befdy * befdy);
if (movdist < radius / 3) {
befpos.x += (nextx - befpos.x) / 32;
befpos.y += (nexty - befpos.y) / 32;
} else {
befpos.x = nextx;
befpos.y = nexty;
}
befpos.x = nextx;
befpos.y = nexty;
break;
}
case IW_IMAGO_AMEBA: {
break;
}
case IW_IMAGO_EEL: {
break;
}
}
track[track_top].x = x;
track[track_top].y = y;
track_top = (track_top + 1) & TRACK_MASK;
//if (age > 3000) dead = true;
}
public function grow(step : int) : void
{
if (step != 0) {
grow_target = age + step;
if (grow_target < 1) grow_target = 1;
else if (grow_target > 1500) grow_target = 1500;
} else grow_target = 0;
}
public function turn(level : Number) : void
{
turn_next = level;
}
public function draw(target : BitmapData, filter : ShaderFilter ) : void
{
var elements : int = 1;
switch (lifeCycle) {
case IW_EGG: elements = 1; break;
case IW_LARVAL: elements = 2; break;
case IW_METAMORPHOSE: if (state > 60) elements = 4; else elements = 2; break;
case IW_IMAGO_WORM: elements = 4; break;
case IW_IMAGO_AMEBA: elements = 4; break;
case IW_IMAGO_EEL: elements = 4; break;
}
for (var ghost : int = 0; ghost < elements; ghost++) {
var xx : int, yy : int, rr : int;
rr = radius;
switch (lifeCycle) {
case IW_METAMORPHOSE: {
if (ghost > 1) {
rr = radius * ((state-60) / 60)*0.8 ;
xx = (x - rr) >> 0;
yy = (y - rr) >> 0;
} else {
if (ghost & 1) {
rr = rr * 0.8;
xx = (befpos.x - rr) >> 0;
yy = (befpos.y - rr) >> 0;
} else {
xx = (x - rr) >> 0;
yy = (y - rr) >> 0;
}
}
break;
}
case IW_IMAGO_EEL:
{
rr = rr*0.9;
xx = (track[ (track_top-ghost*8) & TRACK_MASK].x - rr) >> 0;
yy = (track[ (track_top-ghost*8) & TRACK_MASK].y - rr) >> 0;
break;
}
case IW_IMAGO_AMEBA:
{
var phase : Number;
switch (ghost) {
case 0: {
phase = 0;
break;
}
case 1: {
phase = 30;
break;
}
case 2: {
phase = 90;
break;
}
case 3: {
phase = 60;
break;
}
}
xx = (track[ (track_top-ghost*3-1) & TRACK_MASK].x+Math.cos((phase+state)*Math.PI/60)*rr/3 - rr) >> 0;
yy = (track[ (track_top-ghost*3-1) & TRACK_MASK].y+Math.sin((phase+state)*Math.PI/60)*rr/3 - rr) >> 0;
break;
}
default:
{
if (ghost & 1) {
rr = rr * 0.8;
xx = (befpos.x - rr) >> 0;
yy = (befpos.y - rr) >> 0;
} else {
xx = (x - rr) >> 0;
yy = (y - rr) >> 0;
}
}
}
tempPos.x = xx;
tempPos.y = yy;
tempRect.x = tempPos.x;
tempRect.y = tempPos.y;
tempRect.width = width;
tempRect.height = height;
metaImages[rr].workImage.copyPixels( target, tempRect, zeroPoint );
filter.shader.data.fore.input = metaImages[rr].densityImage;
if ((ghost == elements-1) && (lifeCycle != IW_IMAGO_AMEBA)) {
filter.shader.data.typ.value = [2.0, 2.0, 2.0];
filter.shader.data.offset.value = [0.5, 0.5, 0.5];
} else {
filter.shader.data.typ.value = color_typ;
filter.shader.data.offset.value = color_offset;
}
metaImages[rr].workImage.applyFilter( metaImages[rr].workImage, metaImages[rr].workImage.rect, zeroPoint, filter);
target.copyPixels(metaImages[rr].workImage, metaImages[rr].workImage.rect, tempPos);
}
}
public function get radius():int { return _radius; }
public function set radius(value:int):void
{
_radius = value < MAX_RADIUS ? value : MAX_RADIUS;
bitmapData = metaImages[_radius >> 0].densityImage;
}
}
class MetaCircle
{
private var radius : Number = 0;
private var maxdensity : Number = 1;
private var visibleRatio : Number = 0.8;
public var densityImage : BitmapData;
public var workImage : BitmapData;
private var pos : Point = new Point();
public function MetaCircle(r : Number, density : Number )
{
radius = r;
maxdensity = density;
densityImage = new BitmapData(r * 2+1, r * 2+1, true, 0);
workImage = densityImage.clone();
render();
}
public function density(r : Number) : Number
{
if (r < radius) {
var t : Number = (r / radius);
return maxdensity * (1 - t) * (1 - t);
} else {
return 0.0;
}
}
private function render() : void
{
var h : int = densityImage.height;
var w : int = densityImage.width;
var h2 : int = h / 2;
var w2 : int = w / 2;
densityImage.lock();
for (var y : int = 0; y < h; y++ ) {
var rad1 : Number = Math.acos( ((h2-y)/h2) );
var spanr : Number = Math.sin( rad1 ) * h2;
for (var x : int = 0; x < w; x++) {
var r : Number = Math.sqrt( (w2 - x) * (w2 - x) + (h2 - y) * (h2 - y) );
var a : uint = density(r) * 255;
if (a > 0) {
var rad2 : Number = Math.acos(( (w2 - x) / w2));
// 右手座標系 +X=左 +Y=上 +Z=手前
var ny : Number = (h2 - y);
var nx : Number = (Math.cos( rad2 ) * spanr);
var nz : Number = Math.sin( rad2 ) * spanr;
var l : Number = Math.sqrt( nx * nx + ny * ny +nz * nz );
var nv : int = (Math.max(0,Math.min(255, nx / l * 128 + 128)) << 16) | (Math.min(255, ny / l * 128 + 128) << 8) | a;// (Math.min(255, nz / l * 128 + 128));
if (a > 0) {
// 本当はAチャンネルで濃度をあらわしたいが、Aの値を変えるとPixelBenderで参照しているRGBも変わってしまうのでしかたなくBに濃度を格納
densityImage.setPixel32(x, y, (a << 24) | nv );
}
}
}
}
densityImage.unlock();
}
public function drawTo(target : BitmapData, x : Number, y : Number) : void
{
pos.x = x-radius;
pos.y = y-radius;
target.copyPixels(densityImage, densityImage.rect, pos, null, null, true);
}
}
import mx.utils.Base64Decoder;
class MetaEffectPB extends Shader
{
// [Embed(source = 'MetaEffectPB.pbj', mimeType = 'application/octet-stream')]
// private var pbj : Class;
private var bcode : String =
"pQEAAACkCQBEcm9wV2F0ZXKgDG5hbWVzcGFjZQBqcC5saW1hY29uAKAMdmVuZG9yAEVTVgCgCHZl"+
"cnNpb24AAgCgDGRlc2NyaXB0aW9uAG1ldGFOVgChAQIAAAxfT3V0Q29vcmQAoQECAAADcG9zaXRp"+
"b24AoQEDAQAOdHlwAKIDZGVmYXVsdFZhbHVlAEAAAABAAAAAQAAAAKEBAwIADm9mZnNldACiA2Rl"+
"ZmF1bHRWYWx1ZQA/AAAAPwAAAD8AAACjAARiYWNrAKMBBGZvcmUAoQIEAwAPZGVzdAAdBADBAAAQ"+
"AB0EADEEABAAAgQAMQAAsAAxBQDxBACwAR0GAPMFABsAMQUA8QQAEAAdBwDzBQAbAB0BABAGAMAA"+
"AQEAEAcAwAAdAwAQAQDAADIBABAAAAAAKgEAEAYAwAAdAYCAAIAAADQAAAABgAAAMgEAED8AAAAd"+
"BQDiBgAYAAIFAOIBAPwAMgEAEEAAAAAdCADiBQAYAAMIAOIBAPwAMgEAED8AAAAdBQDiBwAYAAIF"+
"AOIBAPwAMgEAEEAAAAAdCQDiBQAYAAMJAOIBAPwAHQUA4ggAGAABBQDiCQAYAB0IAOIFABgAJAEA"+
"EggAGAAdAgAQAQDAAAQFAOICAPwAAwUA4ggAGAAdCADiBQAYADIBABAAAAAAKgEAEAgAAAAdAYBA"+
"AIAAADQAAAABgEAABAEAEAEAAAADAQAQCAAAAB0EACABAMAAAQQAIAIAAAAdCACABACAADUAAAAA"+
"AAAABAEAEAEAAAADAQAQCAAAAB0EACACAAAAAgQAIAEAwAAdCACABACAADYAAAAAAAAAMgEAEAAA"+
"AAAqAQAQCABAAB0BgEAAgAAANAAAAAGAQAAEAQAQAQBAAAMBABAIAEAAHQQAIAEAwAABBAAgAgBA"+
"AB0IAEAEAIAANQAAAAAAAAAEAQAQAQBAAAMBABAIAEAAHQQAIAIAQAACBAAgAQDAAB0IAEAEAIAA"+
"NgAAAAAAAAAyAQAQAAAAACoBABAIAIAAHQGAQACAAAA0AAAAAYBAAAQBABABAIAAAwEAEAgAgAAd"+
"BAAgAQDAAAEEACACAIAAHQgAIAQAgAA1AAAAAAAAAAQBABABAIAAAwEAEAgAgAAdBAAgAgCAAAIE"+
"ACABAMAAHQgAIAQAgAA2AAAAAAAAAB0DAOIIABgANQAAAAAAAAAdAwDiBwAYADYAAAAAAAAA";
public function MetaEffectPB()
{
/*
var code : ByteArray = (new pbj()) as ByteArray;
super( code );
*/
var dec : Base64Decoder = new Base64Decoder();
dec.decode( bcode );
super(dec.toByteArray());
}
}
/*
<languageVersion : 1.0;>
kernel DropWater
< namespace : "jp.limacon";
vendor : "ESV";
version : 2;
description : "metaNV"; >
{
parameter float2 position;
input image4 back;
input image4 fore;
output pixel4 dest;
void evaluatePixel()
{
float2 curPos = outCoord();
pixel4 f0 = sampleNearest(fore, curPos-position);
pixel4 b0 = sampleNearest(back, curPos);
dest.a = f0.a+b0.a;
if (f0.a > 0.0) {
float3 v = (f0.xyz-0.5)*2.0 + (b0.xyz-0.5)*2.0;//(f0.xyz*2.0-1.0) + (b0.xyz*2.0-1.0);
float l = length( v );
v = v/l;
if (v.r > 0.0) v.r = v.r/2.0+0.5; else v.r = 0.5-v.r/2.0;
if (v.g > 0.0) v.g = v.g/2.0+0.5; else v.g = 0.5-v.g/2.0;
if (v.b > 0.0) v.b = v.b/2.0+0.5; else v.b = 0.5-v.b/2.0;
dest.rgb = v;
} else {
dest.rgb = b0.rgb;
}
}
}
*/