BitmapDataで3Dを表現してみる。(任意の軸で回転させてみた)
作成中
BitmapDataで3Dを表現してみる。 ver.2
マウスの座標に応じて軸が変化します。
色は読込時に決定されます。
奇麗な色だったら良いのですが
/**
* Copyright code ( http://wonderfl.net/user/code )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5VCy
*/
/* 作成中
BitmapDataで3Dを表現してみる。 ver.2
マウスの座標に応じて軸が変化します。
色は読込時に決定されます。
奇麗な色だったら良いのですが
*/
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
[SWF(width = "512", height = "600", frameRate = "30" )]
import flash.text.TextField;
public class main_R extends Sprite
{
private var fromPoint:Vector3D;
private var canvas:BitmapData;
private var dammy:Sprite;
private const PI2:Number = Math.PI * 2; //phi
private var beemBMD:BitmapData;
private var fBMD:BitmapData;
private var Beems:Vector.<BeemManager>;
private var BeemPool:Vector.<BeemManager>;
private const size:Number=0.5;
private const color:uint = 0xffffff;// * ((Math.random() * 0.1) + 0.9);
private const ADD_NUM:uint = 50;
private const RADIUS:uint = 200;
private var BLUR:Vector.<Number>;
private const SPEED:uint = 1;
private const fromOffset:uint = 180;
private var base:Sprite;
private var isMouseOut:Boolean=true;
private var axisAngle:Number = PI2 / 3;
private var myAngle:Number = Math.PI;
private var pat:Shape;
private var t1:TextField;
private var t2:TextField;
public function main_R()
{
setInit();
setCanvas();
createBEEMBMD();
//
forDebug();
addEventListener(Event.ENTER_FRAME, loopHandler);
stage.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
stage.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
}
private function setInit():void
{
stage.quality = StageQuality.MEDIUM;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
fromPoint = new Vector3D(0, 0, 0);
this.transform.perspectiveProjection.projectionCenter = new Point(stage.stageWidth / 2, stage.stageHeight / 2);
base = new Sprite();
addChild(base);
base.x = stage.stageWidth / 2;
base.y = stage.stageHeight / 2;
base.z = 0;
base.graphics.beginFill(0x000000, 0);
base.graphics.drawRect( -stage.stageWidth / 2, -stage.stageHeight / 2, stage.stageWidth, stage.stageHeight);
base.graphics.endFill();
dammy = new Sprite();
base.addChild(dammy);
dammy.x = 0;
dammy.y = 0;
dammy.z = 0;
pat = new Shape();
dammy.addChild(pat);
BeemPool = new Vector.<BeemManager>();
Beems = new Vector.<BeemManager>();
BLUR = new Vector.<Number>(3);
BLUR[0] = Math.random()*Math.random();
BLUR[1] = Math.random()*Math.random();
BLUR[2] = Math.random()*Math.random();
}
private function setCanvas():void
{
canvas = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
addChild(new Bitmap(canvas));
}
private function createBEEMBMD():void
{
var beem:Shape = new Shape();
var beemG:Graphics = beem.graphics;
beemG.beginFill(color);
beemG.drawCircle(size, size,size);
beemG.endFill();
beemBMD = new BitmapData(beem.width, beem.height, true, 0);
beemBMD.draw(beem);
//キラキラ用
fBMD = new BitmapData(stage.stageWidth/4, stage.stageHeight/4, false, 0x000000);
var bm:Bitmap = addChild(new Bitmap(fBMD, PixelSnapping.NEVER, true)) as Bitmap;
bm.scaleX = bm.scaleY = 4;
bm.blendMode = BlendMode.ADD;
}
private function loopHandler(e:Event):void
{
canvas.lock();
var ct:ColorTransform = new ColorTransform (BLUR[0], BLUR[1],BLUR[2]);
canvas.colorTransform(canvas.rect, ct);
createBEEM();
rotationBeems();
for (var i:uint = 0; i < Beems.length; i++)
{
var beem:BeemManager = Beems[i];
convert2D(beem);
if (beem.radius >= RADIUS){
poolObject(i);
continue;
}
canvas.copyPixels(beemBMD, beemBMD.rect , beem.toPoint2D);
//caution2
// canvas.copyPixels(beemBMD, beem.rect, beem.toPoint2D, alphaBMD, new Point(beem.depth, 0), false);
}
fBMD.draw(canvas, new Matrix(0.25, 0, 0, 0.25));
canvas.unlock();
t1.text="処理対象のBEEMの数 : "+Beems.length.toString();
t2.text="プール中のBEEMの数 : "+BeemPool.length.toString();
}
private function rotationBeems():void
{
if (isMouseOut) {
myAngle *= 0.97;
}else {
var nabs:uint=Math.abs(mouseX-stage.stageWidth/2);
var mabs:uint=Math.abs(mouseY-stage.stageHeight/2);
myAngle = Math.min(RADIUS, Math.max(mabs,nabs))/100;
}
var myAxis:Number = Math.PI/2 + Math.atan2((mouseY - stage.stageHeight/2), (mouseX - stage.stageWidth/2));
var vx:Number = Math.cos(myAxis);
var vy:Number = Math.sin(myAxis);
var axis:Vector3D = new Vector3D(vx, vy, 0);
dammy.transform.matrix3D.appendRotation(myAngle, axis);
}
private function getabs(n:uint):uint{
var m:uint=n>>31;
return n^m-m;
}
private function poolObject(i:uint):void
{
BeemPool.push(Beems[i]);
Beems.splice(i, 1);
}
private function createBEEM():void
{
for (var i:uint = 0; i < ADD_NUM; i++)
{
var newBeem:BeemManager;
if ( BeemPool.length != 0){
newBeem = BeemPool.pop();
}else{
newBeem = new BeemManager();
}
newBeem.angleAlpha = Math.random() * Math.PI;
newBeem.angleBeta = Math.random() * PI2;
newBeem.radius = (RADIUS - fromOffset) * Math.random() + fromOffset;
newBeem.depth = 0;
Beems.push(newBeem);
}
}
private function convert2D(beem:BeemManager):void
{
beem.radius += SPEED;
var posX:Number = beem.radius * Math.cos(beem.angleBeta) * Math.sin(beem.angleAlpha);
var posY:Number = beem.radius* Math.sin(beem.angleBeta);
var posZ:Number = beem.radius * Math.cos(beem.angleBeta) * Math.cos(beem.angleAlpha);
pat.x = posX;
pat.y = posY;
pat.z = posZ;
var mtrx3D:Matrix3D = pat.transform.getRelativeMatrix3D(dammy);
beem.toPoint3D = new Vector3D(mtrx3D.position.x, mtrx3D.position.y, mtrx3D.position.z);
beem.toPoint2D = dammy.local3DToGlobal(beem.toPoint3D);
}
private function mouseOverHandler(e:MouseEvent):void
{
isMouseOut = false;
}
private function mouseOutHandler(e:MouseEvent):void
{
isMouseOut = true;
}
private function forDebug():void
{
t1=new TextField();
addChild(t1);
t1.autoSize="left";
t1.textColor=0xffffff;
t2=new TextField();
t2.autoSize="left";
addChild(t2);
t2.textColor=0xffffff;
t2.y=20;
}
}
}
import flash.geom.*;
class BeemManager
{
public var toPoint3D:Vector3D;
public var toPoint2D:Point;
public var radius:Number;
public var angleAlpha:Number;
public var angleBeta:Number;
public var depth:Number;
public var rect:Rectangle;
public function BeemManager()
{
toPoint3D = new Vector3D();
toPoint2D = new Point();
radius = 0;
angleAlpha = 0;
angleBeta = 0;
depth = 0;
rect = new Rectangle();
}
}