Beautifl - Flash Gallery

Thumbnail : [Stardust] + [Alternativa3D]
[Stardust] + [Alternativa3D]
paq 2010-01-28 MIT License

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

/*
 * Stardust + Alternativa3D
 * 
 * @author paq89
 */
package
{
	import flash.display.Sprite;
	import net.hires.debug.Stats;
	
	[SWF(width=465, height=465, backgroundColor=0x000000, frameRate=60)]
	public class Init extends Sprite
	{
		public function Init():void 
		{
			addChild(new Main());
			addChild(new Stats());
		}
		
	}
}

import alternativ5.engine3d.controllers.CameraController;
import alternativ5.engine3d.core.Camera3D;
import alternativ5.engine3d.core.Object3D;
import alternativ5.engine3d.core.Scene3D;
import alternativ5.engine3d.core.Surface;
import alternativ5.engine3d.display.View;
import alternativ5.engine3d.materials.DevMaterial;
import alternativ5.engine3d.materials.FillMaterial;
import alternativ5.engine3d.materials.WireMaterial;
import alternativ5.engine3d.primitives.Box;
import alternativ5.engine3d.primitives.Plane;
import alternativ5.types.Point3D;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import frocessing.color.ColorHSV;
import idv.cjcat.stardust.common.actions.Age;
import idv.cjcat.stardust.common.actions.AlphaCurve;
import idv.cjcat.stardust.common.actions.DeathLife;
import idv.cjcat.stardust.common.actions.ScaleCurve;
import idv.cjcat.stardust.common.clocks.Clock;
import idv.cjcat.stardust.common.clocks.SteadyClock;
import idv.cjcat.stardust.common.events.EmitterEvent;
import idv.cjcat.stardust.common.initializers.Life;
import idv.cjcat.stardust.common.math.UniformRandom;
import idv.cjcat.stardust.common.particles.Particle;
import idv.cjcat.stardust.common.particles.ParticleIterator;
import idv.cjcat.stardust.common.renderers.Renderer;
import idv.cjcat.stardust.common.utils.construct;
import idv.cjcat.stardust.threeD.actions.Deflect3D;
import idv.cjcat.stardust.threeD.actions.Gravity3D;
import idv.cjcat.stardust.threeD.actions.Move3D;
import idv.cjcat.stardust.threeD.actions.Spin3D;
import idv.cjcat.stardust.threeD.deflectors.PlaneDeflector;
import idv.cjcat.stardust.threeD.emitters.Emitter3D;
import idv.cjcat.stardust.threeD.fields.UniformField3D;
import idv.cjcat.stardust.threeD.initializers.Initializer3D;
import idv.cjcat.stardust.threeD.initializers.Omega3D;
import idv.cjcat.stardust.threeD.initializers.Position3D;
import idv.cjcat.stardust.threeD.initializers.Rotation3D;
import idv.cjcat.stardust.threeD.initializers.Velocity3D;
import idv.cjcat.stardust.threeD.particles.Particle3D;
import idv.cjcat.stardust.threeD.zones.CubeZone;
import idv.cjcat.stardust.threeD.zones.SinglePoint3D;
import idv.cjcat.stardust.threeD.zones.SphereCap;

/**
 * BasicTemplate for Alternativa3D
 * Alternativa3Dを扱いやすくするためのテンプレートです
 * @author Yasu
 */
class BasicTemplate extends Sprite{
	/**
	 * シーンインスタンスです。
	 */
	public var scene:Scene3D;
	/**
	 * ビューインスタンスです。
	 */
	public var view:View;
	/**
	 * カメラインスタンスです。
	 */
	public var camera:Camera3D;
	/**
	 * カメラコントローラーです。
	 */
	public var cameraContoller:CameraController;
	
	private var _viewWidth:int;
	private var _viewHeight:int;
	private var _scaleToStage:Boolean;

	/**
	 * 新しい BasicTemplate インスタンスを作成します。
	 * @param	viewWidth
	 * @param	viewHeight
	 * @param	scaleToStage
	 */
	public function BasicTemplate(viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true) {
		_viewWidth = viewWidth;
		_viewHeight = viewHeight;
		_scaleToStage = scaleToStage;
		
		// Creating scene
		scene = new Scene3D();
		scene.splitAnalysis = false; // not analysis for performance
		scene.root = new Object3D();
		
		// Adding camera
		camera = new Camera3D();
		camera.z = -1000;
		scene.root.addChild(camera);
		
		// camera contoller
		cameraContoller = new CameraController(this);
		cameraContoller.camera = camera;
		
		// set view
		view = new View();
		view.camera = camera;
		addChild(view);
		
		// stage
		if (stage) init();
		else addEventListener(Event.ADDED_TO_STAGE, init);
	}
	
	/**
	 * 初期化されたときに実行されるイベントです。
	 * 初期化時に実行したい処理をオーバーライドして記述します。
	 */
	protected function atInit():void {}
	
	/**
	 * 初期化されたときに実行されるイベントです。
	 * 初期化時に実行したい処理を記述します。
	 */
	private var _onInit:Function = function():void { };
	public function get onInit():Function { return _onInit; }
	public function set onInit(value:Function):void {
		_onInit = value;
	}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング前に実行したい処理をオーバーライドして記述します。
	 */
	protected function atPreRender():void {}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング前に実行したい処理を記述します。
	 */
	private var _onPreRender:Function = function():void{};
	public function get onPreRender():Function { return _onPreRender; }
	public function set onPreRender(value:Function):void {
		_onPreRender = value;
	}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング後に実行したい処理をオーバーライドして記述します。
	 */
	protected function atPostRender():void {
	}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング後に実行したい処理を記述します。
	 */
	protected var _onPostRender:Function = function():void{};
	public function get onPostRender():Function { return _onPostRender; }
	public function set onPostRender(value:Function):void {
		_onPostRender = value;
	}
	
	/**
	 * レンダリングを開始します。
	 */
	public function startRendering():void {
		addEventListener(Event.ENTER_FRAME, onRenderTick);
	}
	/**
	 * レンダリングを停止します。
	 */
	public function stopRendering():void {
		removeEventListener(Event.ENTER_FRAME, onRenderTick);
	}
	
	/**
	 * シングルレンダリング(レンダリングを一回だけ)を実行します。
	 */
	public function singleRender():void {
		onRenderTick();
	}
	
	/**
	 * @private
	 */
	private function init(e:Event = null):void {
		stage.scaleMode = StageScaleMode.NO_SCALE;
		stage.align = StageAlign.TOP_LEFT;
		stage.quality = StageQuality.HIGH;

		// resize
		stage.addEventListener(Event.RESIZE, onResize);
		onResize(null);
		
		// render
		startRendering();
		
		atInit();
		_onInit();
		
	}
	
	/**
	 * @private
	 */
	private function onRenderTick(e:Event = null):void {
		atPreRender();
		_onPreRender();
		scene.calculate();
		atPostRender();
		_onPostRender();
	}
	
	/**
	 * @private
	 */
	private function onResize(event:Event = null):void {
		if (_scaleToStage) {
			view.width = stage.stageWidth;
			view.height = stage.stageHeight;
		}else {
			view.width = _viewWidth;
			view.height = _viewHeight;
		}
	}
}

//----------------------------------------------------------------------------------------------------------

class Main extends BasicTemplate
{
	private var emitter:Alternativa3DEmitter;
	private var container:Object3D;
	
	/*
	 * コンストラクタ
	 */
	public function Main():void
	{
		super(465, 465);
	}
	
	/*
	 * 初期化時に実行する処理
	 */
	override protected function atInit():void 
	{
		// パーティクルを格納するためのObject3Dを作る
		container = new Object3D();
		scene.root.addChild(container);
		
		//床を作る
		var floor:Plane = new Plane(2000, 2000, 4, 4, false);
		floor.cloneMaterialToAllSurfaces(new FillMaterial(0xFFFFFF, 0.1, "normal", 1, 0xFFFFFF));
		floor.rotationX = 90 * Math.PI / 180;
		container.addChild(floor);
		
		// カメラ
		camera.y = -200;
		cameraContoller.lookAt(new Point3D());
		
		// パーティクルシステムの構築
		emitter = new Alternativa3DEmitter(new SteadyClock(0.1));
		var renderer:Alternativa3DObject3DRenderer = new Alternativa3DObject3DRenderer(container);
		renderer.addEmitter(emitter);
	}
	
	/*
	 * レンダリング前に実行する処理
	 */
	override protected function atPreRender():void
	{
		// エミッター更新
		emitter.step();
		
		container.rotationY += 0.2 * Math.PI / 180;
	}
	
}

/*
 * Emitter
 * @author paq
 */
class Alternativa3DEmitter extends Emitter3D
{
	public function Alternativa3DEmitter(clock:Clock)
	{
		super(clock);
		
		var omegaRand:UniformRandom = new UniformRandom(0, 4);
		
		addInitializer(new Position3D(new SinglePoint3D()));
		addInitializer(new Omega3D(omegaRand, omegaRand, omegaRand));
		addInitializer(new Object3DClass(Cube));
		addInitializer(new Velocity3D(new SphereCap(0, 0, 0, 30, 40, 15)));
		addInitializer(new Life(new UniformRandom(100, 50)));
		addInitializer(new Rotation3D(new UniformRandom(0, 180), new UniformRandom(0, 180), new UniformRandom(0, 180)));
		
        var field:UniformField3D = new UniformField3D(0, 1, 0);
        var gravity:Gravity3D = new Gravity3D();
        gravity.addField(field);
		
        var deflect:Deflect3D = new Deflect3D();
        deflect.addDeflector(new PlaneDeflector(0, 0, 0, 0, -1, 0));
		
		addAction(gravity);
		addAction(deflect);
		addAction(new Age());
		addAction(new DeathLife());
		addAction(new Move3D());
		addAction(new Spin3D());
		addAction(new ScaleCurve(10, 10));
		addAction(new AlphaCurve(10, 10));
	}
}

/*
 * パーティクル
 * @author paq
 */
class Cube extends Box
{
	static private const hsv:ColorHSV = new ColorHSV(0, 0.3, 1);
	public function Cube()
	{
		super();
		hsv.h += 4;
		hsv.s = 0.7;
		setMaterialToSurface(new FillMaterial(hsv.value32), 'front');  
		hsv.s += 2;
		setMaterialToSurface(new FillMaterial(hsv.value32), 'back');  
		hsv.s += 2;
		setMaterialToSurface(new FillMaterial(hsv.value32), 'top');  
		hsv.s += 2;
		setMaterialToSurface(new FillMaterial(hsv.value32), 'bottom');  
		hsv.s += 2;
		setMaterialToSurface(new FillMaterial(hsv.value32), 'left');  
		hsv.s += 2;
		setMaterialToSurface(new FillMaterial(hsv.value32), 'right');  
	}
}

//----------------------------------------------------------------------------------------------------------

/*
 * Alternativa3D用レンダラー
 * @author paq
 */
class Alternativa3DObject3DRenderer extends Renderer
{
	static private const PI:Number = 3.14;
	private var container:Object3D;
	
	public function Alternativa3DObject3DRenderer(container:Object3D = null)
	{
		this.container = container;
	}
	
	override protected function particlesAdded(e:EmitterEvent):void
	{
		if (!container) return;
		var particle:Particle3D;
		var iter:ParticleIterator = e.particles.getIterator();
		while (particle = iter.particle as Particle3D) {
			var obj3D:Object3D = particle.target as Object3D;
			container.addChild(obj3D);
			particle.dictionary[Alternativa3DObject3DRenderer] = container;
			
			iter.next();
		}
	}
	
	override protected function particlesRemoved(e:EmitterEvent):void
	{
		var particle:Particle3D;
		var iter:ParticleIterator = e.particles.getIterator();
		while (particle = iter.particle as Particle3D) {
			var obj3D:Object3D = particle.target as Object3D;
			var container:Object3D = particle.dictionary[Alternativa3DObject3DRenderer] as Object3D;
			
			container.removeChild(obj3D);
			
			iter.next();
		}
	}
	
	override protected function render(e:EmitterEvent):void
	{
		var particle:Particle3D;
		var iter:ParticleIterator = e.particles.getIterator();
		while (particle = iter.particle as Particle3D) {
			var obj3D:* = particle.target;
			
			obj3D.x = particle.x;
			obj3D.y = particle.y;
			obj3D.z = particle.z;
			obj3D.rotationX = particle.rotationX * PI / 180;
			obj3D.rotationY = particle.rotationY * PI / 180;
			obj3D.rotationZ = particle.rotationZ * PI / 180;
			obj3D.scaleX = obj3D.scaleY = obj3D.scaleZ = particle.scale;
			// 特に使い道のないparticle.colorをalpha記録用として使う....。
			if (particle.alpha != particle.color)
			{
				var surf:/*Surfaces*/Array = obj3D.surfaces.toArray(true);
				var len:int = surf.length;
				for (var i:int = 0; i < len; i++) 
				{
					surf[i].material.alpha = particle.alpha;
				}
			}
			particle.color = particle.alpha;
			
			iter.next();
		}
	}
	
	
	//XML
	//------------------------------------------------------------------------------------------------
	
	override public function getXMLTagName():String {
		return "Alternativa3DObject3DRenderer";
	}
	
	//------------------------------------------------------------------------------------------------$
	//end of XML
}

/*
 * Alternativa3D用アクション
 * @author paq
 */
class Object3DClass extends Initializer3D {
	
	private var _displayObject3DClass:Class;
	private var _constructorParams:Array;
	public function Object3DClass(displayObject3DClass:Class = null, constructorParams:Array = null) {
		this.displayObject3DClass = displayObject3DClass;
		this.constructorParams = constructorParams;
	}
	
	public function get displayObject3DClass():Class { return _displayObject3DClass; }
	public function set displayObject3DClass(value:Class):void {
		if (!value) value = Object3D;
		_displayObject3DClass = value;
	}
	
	public function get constructorParams():Array { return _constructorParams; }
	public function set constructorParams(value:Array):void {
		if (!value) value = [];
		_constructorParams = value;
	}
	
	override public function initialize(particle:Particle):void {
		var obj3D:Object3D = construct(_displayObject3DClass, _constructorParams) as Object3D;
		particle.target = obj3D;
	}
	
	
	//XML
	//------------------------------------------------------------------------------------------------
	
	override public function getXMLTagName():String {
		return "Object3DClass";
	}
	
	//------------------------------------------------------------------------------------------------
	//end of XML
}