Beautifl - Flash Gallery

Thumbnail : [motif]燕子花図
[motif]燕子花図
sekiryou 2010-05-28 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

/**
* [motif]燕子花図
* @author Masayuki Komatsu / sekiryou.com
* http://twitter.com/sekiryou_com
*/
package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix3D;
	import flash.geom.PerspectiveProjection;
	import flash.geom.Utils3D;
	import flash.geom.Vector3D;
	
	[SWF(width = 465, height = 465, backgroundColor = 0x888822, frameRate = 30)]
	
	public class Kakitsubata extends Sprite {
		private var _canvas:BitmapData;
		private var world:Sprite;
		
		private var projection:PerspectiveProjection;
		private var projectionMatrix3D:Matrix3D;
		private var mtx3D:Matrix3D = new Matrix3D();
		private var greenVerts:Vector.<Number> = new Vector.<Number>();
		private var bloomVerts:Vector.<Number> = new Vector.<Number>();
		private var greenProjectedVerts:Vector.<Number> = new Vector.<Number>();
		private var bloomProjectedVerts:Vector.<Number> = new Vector.<Number>();
		private var gIndicesVerts:Vector.<int> = new Vector.<int>();
		private var bIndicesVerts:Vector.<int> = new Vector.<int>();
		private var uvts:Vector.<Number> = new Vector.<Number>();
		
		private const flowerCount:int = 16;
		private var flowers:Vector.<Flower> = new Vector.<Flower>();
		public function Kakitsubata() {
			init();
		}
		private function init():void {
			world = new Sprite();
			addChild(world);
			world.x = 465 * 0.5;
			world.y = 465 * 0.5 - 280;
			
			var surface:BitmapData = new BitmapData(465, 465, true, 0x00000000);
			var randomSeed:Number = Math.floor(Math.random() * 0xFFFFFF);
			surface.perlinNoise(465/4, 465/10, 16, randomSeed, false, true, 1 | 2 | 4 | 8, true);
			var ctf:ColorTransform = new ColorTransform();
			ctf.alphaMultiplier = 0.7;
			ctf.redMultiplier = 0.5;
			ctf.greenMultiplier = 0.5;
			ctf.blueMultiplier = 0.5;
			surface.colorTransform(surface.rect, ctf);
			var texture:Bitmap = new Bitmap(surface);
			addChild(texture);
			
			projection = new PerspectiveProjection();
			projection.fieldOfView = 60;
			projectionMatrix3D = projection.toMatrix3D();
			
			var i:int;
			var j:int;
			var k:int;
			var len:int;
			var verticesLen:int;
			var indicesLen:int;
			
			for (i = 0; i < flowerCount; i++ ) {
				var tmpFlower:Flower = new Flower(Math.random() * 360 - 180, 0, Math.random() * 360 - 180);
				flowers.push(tmpFlower);
			}
			
			var gTotalIndices:int = 0;
			var bTotalIndices:int = 0;
			for (i = 0; i < flowerCount; i++ ) {
				//STEM
				len = flowers[i].stem.vertex.length;
				for (k = 0; k < len; k++) {
					greenVerts.push(flowers[i].stem.vertex[k].x, flowers[i].stem.vertex[k].y, flowers[i].stem.vertex[k].z);
				}
				verticesLen = flowers[i].stem.indices.length;
				for (k = 0; k < verticesLen; k++) {
					gIndicesVerts.push(flowers[i].stem.indices[k] + gTotalIndices);
				}
				gTotalIndices += len;
				//LEAF
				len = flowers[i].leafs.length;
				for (j = 0; j < len; j++ ) {
					verticesLen = flowers[i].leafs[j].vertex.length;
					for (k = 0; k < verticesLen; k++ ) {
						greenVerts.push(flowers[i].leafs[j].vertex[k].x, flowers[i].leafs[j].vertex[k].y, flowers[i].leafs[j].vertex[k].z);
					}
					indicesLen = flowers[i].leafs[j].indices.length;
					for (k = 0; k < indicesLen; k++ ) {
						gIndicesVerts.push(flowers[i].leafs[j].indices[k] + gTotalIndices);
					}
					gTotalIndices += verticesLen;
				}
				
				//OUTPETAL
				len = flowers[i].outPetals.length;
				for (j = 0; j < len; j++ ) {
					verticesLen = flowers[i].outPetals[j].vertex.length;
					for (k = 0; k < verticesLen; k++ ) {
						bloomVerts.push(flowers[i].outPetals[j].vertex[k].x, flowers[i].outPetals[j].vertex[k].y, flowers[i].outPetals[j].vertex[k].z);
					}
					indicesLen = flowers[i].outPetals[j].indices.length;
					for (k = 0; k < indicesLen; k++ ) {
						bIndicesVerts.push(flowers[i].outPetals[j].indices[k] + bTotalIndices);
					}
					bTotalIndices += verticesLen;
				}
				//INPETAL
				len = flowers[i].inPetals.length;
				for (j = 0; j < len; j++ ) {
					verticesLen = flowers[i].inPetals[j].vertex.length;
					for (k = 0; k < verticesLen; k++ ) {
						bloomVerts.push(flowers[i].inPetals[j].vertex[k].x, flowers[i].inPetals[j].vertex[k].y, flowers[i].inPetals[j].vertex[k].z);
					}
					indicesLen = flowers[i].inPetals[j].indices.length;
					for (k = 0; k < indicesLen; k++ ) {
						bIndicesVerts.push(flowers[i].inPetals[j].indices[k] + bTotalIndices);
					}
					bTotalIndices += verticesLen;
				}
			}
			addEventListener(Event.ENTER_FRAME, update);
		}
		private var posX:Number = 0;
		private var posY:Number = 0;
		private var posZ:Number = 0;
		private var rotX:Number = 0;
		private var rotY:Number = 0;
		private var rotZ:Number = 0;
		private var offsetY:Number = 240;
		private var offsetZ:Number = 400;
		private var cnt:Number = 1;
		private function update(e:Event):void {
			rotY += 0.1;
			
			mtx3D.identity();
			mtx3D.appendRotation(rotY, Vector3D.Y_AXIS);
			mtx3D.appendTranslation(posX, posY + offsetY, posZ + offsetZ);
			mtx3D.append(projectionMatrix3D);
			bugfix(mtx3D);
			
			Utils3D.projectVectors(mtx3D, greenVerts, greenProjectedVerts, uvts);
			Utils3D.projectVectors(mtx3D, bloomVerts, bloomProjectedVerts, uvts);
			
			var g:Graphics = world.graphics;
			g.clear();
			g.beginFill(0x003300);
			g.drawTriangles(greenProjectedVerts, gIndicesVerts, null, "none");
			g.endFill();
			
			g.beginFill(0x111177);
			g.drawTriangles(bloomProjectedVerts, bIndicesVerts, null, "none");
			g.endFill();
		}
		private function bugfix(matrix:Matrix3D):void {
			var m1:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]));
			var m2:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
			m1.append( m2 );
			if (m1.rawData[15] == 20) {
				var rawData:Vector.<Number> = matrix.rawData;
				rawData[15] /= 20;
				matrix.rawData = rawData;
			}
		}
	}
}

import flash.geom.Matrix3D;
import flash.geom.Vector3D;
class Flower {
	private var mtx3D:Matrix3D = new Matrix3D();
	private var _stem:Stem;
	private const leafCount:int = 4;
	private var _leafs:Vector.<Leaf> = new Vector.<Leaf>();
	private var _outPetals:Vector.<OutPetal> = new Vector.<OutPetal>();
	private var _inPetals:Vector.<InPetal> = new Vector.<InPetal>();
	private var _px:Number;
	private var _py:Number;
	private var _pz:Number;
	
	public function Flower(px:Number, py:Number, pz:Number) {
		_px = px;
		_py = py;
		_pz = pz;
		init();
		setting();
	}
	private function init():void {
		var i:int;
		_stem = new Stem();
		for (i = 0; i < leafCount; i++ ) {
			_leafs.push(new Leaf());
		}
		for (i = 0; i < 3; i++ ) {
			_outPetals.push(new OutPetal());
			_inPetals.push(new InPetal());
		}
	}
	private function setting():void {
		var i:int;
		var j:int;
		var len:int
		//STEM
		mtx3D.identity();
		mtx3D.appendTranslation(_px, _py, _pz);
		bugfix(mtx3D);
		
		len = _stem.vertex.length;
		for (j = 0; j < len; j++ ) {
			_stem.vertex[j] = mtx3D.transformVector(_stem.vertex[j]);
		}
		//LEAF
		var tmpRot:Number = Math.random() * 360;
		for (i = 0; i < leafCount; i++ ) {
			mtx3D.identity();
			mtx3D.appendTranslation(Math.random() * 2 + 3, 0, Math.random() * 4 - 2);
			mtx3D.appendRotation((360 / leafCount) * i + Math.random() * 10 - 5, Vector3D.Y_AXIS);
			mtx3D.appendRotation(tmpRot, Vector3D.Y_AXIS);
			mtx3D.appendTranslation(_stem.vertex[0].x, _stem.vertex[0].y, _stem.vertex[0].z);
			bugfix(mtx3D);
			
			len = _leafs[i].vertex.length;
			for (j = 0; j < len; j++ ) {
				_leafs[i].vertex[j] = mtx3D.transformVector(_leafs[i].vertex[j]);
			}
		}
		//PETAL
		var lastStemPt:int = _stem.vertex.length - 1;
		tmpRot = Math.random() * 360;
		for (i = 0; i < 3; i++ ) {
			//INPETAL
			mtx3D.identity();
			mtx3D.appendRotation(120 * i + Math.random() * 10 - 5, Vector3D.Y_AXIS);
			mtx3D.appendRotation(tmpRot, Vector3D.Y_AXIS);
			mtx3D.appendTranslation(_stem.vertex[lastStemPt].x, _stem.vertex[lastStemPt].y, _stem.vertex[lastStemPt].z);
			bugfix(mtx3D);
			
			len = _inPetals[i].vertex.length;
			for (j = 0; j < len; j++ ) {
				_inPetals[i].vertex[j] = mtx3D.transformVector(_inPetals[i].vertex[j]);
			}
			//OUTPETAL
			mtx3D.identity();
			mtx3D.appendRotation(120 * i + Math.random() * 10 - 5 + 60, Vector3D.Y_AXIS);
			mtx3D.appendRotation(tmpRot, Vector3D.Y_AXIS);
			mtx3D.appendTranslation(_stem.vertex[lastStemPt].x, _stem.vertex[lastStemPt].y, _stem.vertex[lastStemPt].z);
			bugfix(mtx3D);
			
			len = _outPetals[i].vertex.length;
			for (j = 0; j < len; j++ ) {
				_outPetals[i].vertex[j] = mtx3D.transformVector(_outPetals[i].vertex[j]);
			}
		}
	}
	private function bugfix(matrix:Matrix3D):void {
		var m1:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]));
		var m2:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
		m1.append( m2 );
		if (m1.rawData[15] == 20) {
			var rawData:Vector.<Number> = matrix.rawData;
			rawData[15] /= 20;
			matrix.rawData = rawData;
		}
	}
	public function get stem():Stem { return _stem; }
	public function get leafs():Vector.<Leaf> { return _leafs; }
	public function get outPetals():Vector.<OutPetal> { return _outPetals; }
	public function get inPetals():Vector.<InPetal> { return _inPetals; }
}

import flash.geom.Vector3D;
class Stem {
	private var _vertex:Vector.<Vector3D> = new Vector.<Vector3D>();
	private var _indices:Vector.<int> = new Vector.<int>();
	public function Stem() {
		var highly:Number = Math.random() * 10;
		_vertex.push(new Vector3D(1.2, 0, 0));
		_vertex.push(new Vector3D(-1.2, 0, 0));
		_vertex.push(new Vector3D(1.2, -85 + highly, 0));
		_vertex.push(new Vector3D(-1.2, -85 + highly, 0));
		_vertex.push(new Vector3D(0, 0, 1.2));
		_vertex.push(new Vector3D(0, 0, -1.2));
		_vertex.push(new Vector3D(0, -85 + highly, 1.2));
		_vertex.push(new Vector3D(0, -85 + highly, -1.2));
		_vertex.push(new Vector3D(0, -85 + highly, 0));
		_indices.push(0, 3, 1);
		_indices.push(0, 2, 3);
		_indices.push(4, 7, 5);
		_indices.push(4, 6, 7);
	}
	public function set vertex(value:Vector.<Vector3D>):void {
		_vertex = value;
	}
	public function get vertex():Vector.<Vector3D> {
		return _vertex;
	}
	public function get indices():Vector.<int> {
		return _indices;
	}
	public function set indices(value:Vector.<int>):void {
		_indices = value;
	}
}

import flash.geom.Vector3D;
class Leaf {
	private var _vertex:Vector.<Vector3D> = new Vector.<Vector3D>();
	private var _indices:Vector.<int> = new Vector.<int>();
	public function Leaf() {
		_vertex.push(new Vector3D(-2, 0, 04 + rnd(1)));
		_vertex.push(new Vector3D(0, 0, 00 + rnd(1)));
		_vertex.push(new Vector3D(-2, 0, -4 + rnd(1)));
		_vertex.push(new Vector3D(28 + rnd(6), -80 + rnd(4), 00  + rnd(1)));
		_indices.push(0, 3, 1);
		_indices.push(1, 3, 2);
	}
	private function rnd(range:Number):Number {
		return Math.random() * range - range * 0.5;
	}
	public function get vertex():Vector.<Vector3D> {
		return _vertex;
	}
	public function set vertex(value:Vector.<Vector3D>):void {
		_vertex = value;
	}
	public function get indices():Vector.<int> {
		return _indices;
	}
	public function set indices(value:Vector.<int>):void {
		_indices = value;
	}
}

import flash.geom.Vector3D;
class InPetal {
	private var _vertex:Vector.<Vector3D> = new Vector.<Vector3D>();
	private var _indices:Vector.<int> = new Vector.<int>();
	public function InPetal() {
		_vertex.push(new Vector3D(1, 0, 1));
		_vertex.push(new Vector3D(1, 0, -1));
		_vertex.push(new Vector3D(5, -4, 3));
		_vertex.push(new Vector3D(7, -6, 0));
		_vertex.push(new Vector3D(5, -4, -3));
		_vertex.push(new Vector3D(6, -7, 4));
		_vertex.push(new Vector3D(9, -12, 0));
		_vertex.push(new Vector3D(6, -7, -4));
		_vertex.push(new Vector3D(5, -15, 2));
		_vertex.push(new Vector3D(5, -15, -2));
		_indices.push(0, 2, 3);
		_indices.push(0, 3, 1);
		_indices.push(1, 3, 4);
		_indices.push(2, 5, 6);
		_indices.push(2, 6, 3);
		_indices.push(3, 6, 7);
		_indices.push(3, 7, 4);
		_indices.push(5, 8, 6);
		_indices.push(6, 8, 9);
		_indices.push(6, 9, 7);
	}
	public function get vertex():Vector.<Vector3D> {
		return _vertex;
	}
	public function set vertex(value:Vector.<Vector3D>):void {
		_vertex = value;
	}
	public function get indices():Vector.<int> {
		return _indices;
	}
	public function set indices(value:Vector.<int>):void {
		_indices = value;
	}
}

import flash.geom.Vector3D;
class OutPetal {
	private var _vertex:Vector.<Vector3D> = new Vector.<Vector3D>();
	private var _indices:Vector.<int> = new Vector.<int>();
	public function OutPetal() {
		_vertex.push(new Vector3D(1, 0, 1));
		_vertex.push(new Vector3D(1, 0, -1));
		_vertex.push(new Vector3D(7, -4, 4));
		_vertex.push(new Vector3D(7, -6, 0));
		_vertex.push(new Vector3D(7, -4, -4));
		_vertex.push(new Vector3D(12, 3, 6));
		_vertex.push(new Vector3D(12, -2, 0));
		_vertex.push(new Vector3D(12, 3, -6));
		_vertex.push(new Vector3D(16, 5, 3));
		_vertex.push(new Vector3D(16, 5, -3));
		_indices.push(0, 2, 3);
		_indices.push(0, 3, 1);
		_indices.push(1, 3, 4);
		_indices.push(2, 5, 6);
		_indices.push(2, 6, 3);
		_indices.push(3, 6, 7);
		_indices.push(3, 7, 4);
		_indices.push(5, 8, 6);
		_indices.push(6, 8, 9);
		_indices.push(6, 9, 7);
	}
	public function get vertex():Vector.<Vector3D> {
		return _vertex;
	}
	public function set vertex(value:Vector.<Vector3D>):void {
		_vertex = value;
	}
	public function get indices():Vector.<int> {
		return _indices;
	}
	public function set indices(value:Vector.<int>):void {
		_indices = value;
	}
}