Octopus 2
~ The Painter ~
==> Mouse : Light Source x / y
+ Code Clean up
Thanks :
http://www.miaumiau.cat/2010/03/beziers-our-approach/
http://wonderfl.net/user/yonatan
/**
* Copyright FLASHMAFIA ( http://wonderfl.net/user/FLASHMAFIA )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/8W9T
*/
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Rectangle;
[SWF(width='465', height='465', backgroundColor='0x000000', frameRate='64')]
public class Octopus2App extends Sprite {
private var _lux : LuxMod;
public function Octopus2App() {
stage.stageFocusRect = mouseEnabled = tabEnabled = tabChildren = false;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
addChild(_lux = new LuxMod(new OctopusGenerator(stage.stageWidth, stage.stageHeight)));
stage.addEventListener(Event.ENTER_FRAME, update);
}
private function update(e : Event) : void {
_lux.lightX += (stage.mouseX - _lux.lightX) * 0.05;
_lux.lightY += (stage.mouseY - _lux.lightY) * 0.05;
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.LineScaleMode;
import flash.display.PixelSnapping;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Vector3D;
internal final class OctopusGenerator extends Bitmap {
private const OFFSET : Number = 48;
private const CURVE_QUANT : uint = 16;
private const CURVE_LENGTH : uint = 8;
private const NOISE_AMPLITUDE : Number = 24;
private const TANGENT_OFFSET : Number = 1.8;
private const TIME_SCALE : Number = 72;
/* */
private var _t : Number = 0;
private var _controlPoints : Vector.<Vector.<Vector3D>> = new Vector.<Vector.<Vector3D>>(CURVE_QUANT, true);
private var _startPoints : Vector.<Vector3D> = new Vector.<Vector3D>(CURVE_QUANT, true);
private var _endPoints : Vector3D;
private var _gurfs : Vector.<Number> = new Vector.<Number>(CURVE_QUANT, true);
private var _colors : Vector.<uint> = Vector.<uint>([0x240000, 0xFFFF80, 0xAAFF80, 0x80DDFF, 0xEEFFF0, 0xFFEEF0, 0xFF4080, 0x800040, 0xFFDDBB, 0xFFF0BB, 0xFFFFCC, 0x240000]);
private var _fadeCT : ColorTransform = new ColorTransform(1, 1, 1, 0.99999);
private var _colorIndex : uint = 0;
private var _container : Sprite = new Sprite();
private var _combinatoryData : Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(13, true);
public function OctopusGenerator(w : uint, h : uint) : void {
super(new BitmapData(w, h, false, 0), PixelSnapping.AUTO, false);
_combinatoryData[0] = Vector.<Number>([0]);
_combinatoryData[1] = Vector.<Number>([1]);
_combinatoryData[2] = Vector.<Number>([1, 1]);
_combinatoryData[3] = Vector.<Number>([1, 2, 1]);
_combinatoryData[4] = Vector.<Number>([1, 3, 3, 1]);
_combinatoryData[5] = Vector.<Number>([1, 4, 6, 4, 1]);
_combinatoryData[6] = Vector.<Number>([1, 5, 10, 10, 5, 1]);
_combinatoryData[7] = Vector.<Number>([1, 6, 15, 20, 15, 6, 1]);
_combinatoryData[8] = Vector.<Number>([1, 7, 21, 35, 35, 21, 7, 1]);
_combinatoryData[9] = Vector.<Number>([1, 8, 28, 56, 70, 56, 28, 8, 1]);
_combinatoryData[10] = Vector.<Number>([1, 9, 36, 84, 126, 126, 84, 36, 9, 1]);
_combinatoryData[11] = Vector.<Number>([1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]);
_combinatoryData[12] = Vector.<Number>([1, 11, 56, 165, 330, 462, 462, 330, 165, 56, 11, 1]);
var n : uint = 0;
while (n < CURVE_QUANT) {
_gurfs[n] = 5 - 4 + 8 * Math.random();
_controlPoints[n] = new Vector.<Vector3D>(0, false);
++n;
}
var nn : uint = 0;
while (nn < CURVE_QUANT) {
if (nn != 0) {
_controlPoints[nn].push(_controlPoints[0][0]);
n = 1;
while (n < CURVE_LENGTH) {
var reference : Vector3D = _controlPoints[0][n];
_controlPoints[nn].push(new Vector3D(reference.x + ((Math.random() >= 0.5) ? 1 : -1) * NOISE_AMPLITUDE * Math.random(), reference.y + ((Math.random() >= 0.5) ? 1 : -1) * NOISE_AMPLITUDE * Math.random(), 0, reference.w));
++n;
}
} else {
_controlPoints[nn].push(new Vector3D(0, 0, 0, 1));
n = 1;
while (n < CURVE_LENGTH) {
_controlPoints[nn].push(new Vector3D(OFFSET + Math.random() * (w - 2 * OFFSET), OFFSET + Math.random() * (h - 2 * OFFSET), 0, 1));
++n;
}
}
++nn;
}
n = CURVE_QUANT;
while (--n) {
_startPoints[n] = _controlPoints[n][0];
}
addEventListener(Event.ENTER_FRAME, render, false, 0, true);
}
private function render(e : Event) : void {
var f : Number = _t / TIME_SCALE;
var c1 : uint = _colors[_colorIndex];
var c2 : uint = _colors[_colorIndex + 1];
var r1 : uint = (c1 >> 16) & 0xFF;
var g1 : uint = (c1 >> 8) & 0xFF;
var b1 : uint = c1 & 0xFF;
r1 += uint((((c2 >> 16) & 0xFF) - r1) * f);
g1 += uint((((c2 >> 8) & 0xFF) - g1) * f);
b1 += uint(((c2 & 0xFF) - b1) * f);
var n : uint = CURVE_QUANT;
while (--n) {
_endPoints = bezier(f, _controlPoints[n]);
_container.addChild(new GlowLine(_startPoints[n], _endPoints, ((r1 << 16) | (g1 << 8) | b1), 6 * Math.cos(f), _gurfs[n] / 4));
_startPoints[n] = _endPoints;
}
bitmapData.lock();
bitmapData.colorTransform(bitmapData.rect, _fadeCT);
bitmapData.draw(_container, null, null, null, null, false);
bitmapData.unlock();
while (_container.numChildren > 0) {
_container.removeChildAt(_container.numChildren - 1);
}
_t++;
if (_t == TIME_SCALE) {
_t = n = 0;
var vec1 : Vector3D;
var vec2 : Vector3D;
var vec3 : Vector3D;
while (n < CURVE_QUANT) {
vec1 = _controlPoints[n][CURVE_LENGTH - 2];
(vec3 = (vec2 = _controlPoints[n][(CURVE_LENGTH - 1)]).subtract(vec1)).scaleBy(TANGENT_OFFSET);
(vec3 = vec3.add(vec2)).w = 1;
_controlPoints[n][0] = vec2;
_controlPoints[n][1] = vec3;
var nn : uint;
if (n != 0) {
nn = 2;
while (nn < CURVE_LENGTH) {
var reference : Vector3D = _controlPoints[0][nn];
_controlPoints[n][nn] = new Vector3D(reference.x + ((Math.random() >= 0.5) ? 1 : -1) * NOISE_AMPLITUDE * Math.random(), reference.y + ((Math.random() >= 0.5) ? 1 : -1) * NOISE_AMPLITUDE * Math.random(), 0, reference.w);
++nn;
}
} else {
nn = 2;
while (nn < CURVE_LENGTH) {
_controlPoints[n][nn] = new Vector3D(OFFSET + Math.random() * (width - 2 * OFFSET), OFFSET + Math.random() * (height - 2 * OFFSET), 0, 1);
++nn;
}
}
++n;
}
_colorIndex++;
if (_colorIndex > _colors.length - 2) {
_colorIndex = 0;
}
}
}
private function bezier(t : Number, ctrlp : Vector.<Vector3D>) : Vector3D {
var len : uint = ctrlp.length;
if (_combinatoryData[len] == null) {
_combinatoryData[len] = new Vector.<Number>(0, false);
}
var out : Vector3D = new Vector3D();
var delta : Number = 0;
var n : uint;
while (n <= (len - 1)) {
var coeff : Number = _combinatoryData[len][n] * Math.pow(t, n) * Math.pow((1 - t), (len - 1) - n);
out.x += coeff * ctrlp[n].x * ctrlp[n].w;
out.y += coeff * ctrlp[n].y * ctrlp[n].w;
out.z += coeff * ctrlp[n].z * ctrlp[n].w;
delta += coeff * ctrlp[n].w;
n++;
}
out.x = out.x / delta;
out.y = out.y / delta;
out.z = out.z / delta;
return out;
}
}
internal final class GlowLine extends Shape {
public function GlowLine(startVec : Vector3D, endVec : Vector3D, color : uint, gurf : Number, alpha : Number) {
graphics.lineStyle(gurf, color, alpha, false, LineScaleMode.NONE);
graphics.moveTo(startVec.x, startVec.y);
graphics.lineTo(endVec.x, endVec.y);
filters = [new GlowFilter(color, 0.6, 24, 24, 5, 3)];
}
}
internal final class LuxMod extends Sprite {
private const BUFF_SIZE : uint = 0x8000;
private const PASSES : uint = 6;
private const SCALE : Number = 2;
private const MTX_SCALE : Number = 1 + (SCALE - 1) / (1 << PASSES);
private const SMOOTH : Boolean = true;
/* */
public var lightX : Number;
public var lightY : Number;
/* */
private var _emission : DisplayObject;
private var _light : Bitmap = new Bitmap(null, PixelSnapping.AUTO, false);
private var _cth : ColorTransform = new ColorTransform(0.5, 0.5, 0.5);
private var _bitmapData : BitmapData;
private var _buffer : BitmapData;
private var _sw : int;
private var _sh : int;
private var _mtx : Matrix = new Matrix();
private var _dstp : Point = new Point();
private var _tmp : BitmapData;
public function LuxMod(emission : DisplayObject) {
addChild(_emission = emission);
addChild(_light).blendMode = BlendMode.ADD;
stage ? onStage(null) : addEventListener(Event.ADDED_TO_STAGE, onStage, false, 0, true);
}
private function onStage(e : Event) : void {
if (e) removeEventListener(Event.ADDED_TO_STAGE, onStage);
stage.addEventListener(Event.RESIZE, resize);
resize(null);
addEventListener(Event.ENTER_FRAME, render);
}
private function render(e : Event) : void {
_mtx.copyFrom(_emission.transform.matrix);
_mtx.scale(_bitmapData.width / _sw, _bitmapData.height / _sh);
_bitmapData.lock();
_bitmapData.fillRect(_bitmapData.rect, 0x0);
_bitmapData.draw(_emission, _mtx, null);
var dx : Number = lightX / _sw * _bitmapData.width;
var dy : Number = lightY / _sh * _bitmapData.height;
_mtx.identity();
_mtx.translate(-dx, -dy);
_mtx.scale(MTX_SCALE, MTX_SCALE);
_mtx.translate(dx, dy);
var n : uint = PASSES >> 1;
while (n--) {
_bitmapData.colorTransform(_bitmapData.rect, _cth);
_buffer.copyPixels(_bitmapData, _bitmapData.rect, _dstp);
_buffer.draw(_bitmapData, _mtx, null, BlendMode.ADD, null, false);
_mtx.concat(_mtx);
_tmp = _bitmapData;
_bitmapData = _buffer;
_buffer = _tmp;
}
/* lil trick! */
n = PASSES >> 1;
while (n--) {
_bitmapData.colorTransform(_bitmapData.rect, _cth);
_buffer.copyPixels(_bitmapData, _bitmapData.rect, _dstp);
_buffer.draw(_bitmapData, _mtx, null, BlendMode.ADD, null, true);
_mtx.concat(_mtx);
_tmp = _bitmapData;
_bitmapData = _buffer;
_buffer = _tmp;
}
_bitmapData.unlock();
}
private function resize(e : Event) : void {
_sw = stage.stageWidth;
_sh = stage.stageHeight;
lightX = _sw >> 1;
lightY = _sh >> 1;
if (_bitmapData) _bitmapData.dispose();
if (_buffer) _buffer.dispose();
_bitmapData = _buffer = null;
var buffh : Number = Math.max(1, Math.sqrt(BUFF_SIZE * (_sh / _sw)));
var buffw : Number = Math.max(1, buffh * (_sw / _sh));
_bitmapData = new BitmapData(buffw, buffh, false, 0);
_buffer = _bitmapData.clone();
_light.bitmapData = _bitmapData;
_light.width = _sw;
_light.height = _sh;
_light.smoothing = SMOOTH;
}
}