forked from: [Stardust][PV3D] Depth of field
Changed the use of the "_particlesList" array to Stardust's internal paritcle collection.
/**
* Copyright cjcat2266 ( http://wonderfl.net/user/cjcat2266 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/q5qQ
*/
// forked from paq's [Stardust][PV3D] Depth of field
/**
* Changed the use of the "_particlesList" array to Stardust's internal paritcle collection.
*/
package {
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import idv.cjcat.stardust.common.clocks.SteadyClock;
import idv.cjcat.stardust.common.particles.Particle;
import idv.cjcat.stardust.common.particles.ParticleIterator;
import idv.cjcat.stardust.threeD.papervision3d.renderers.PV3DDisplayObject3DRenderer;
import org.papervision3d.core.effects.view.ReflectionView;
import org.papervision3d.objects.DisplayObject3D;
/**
* @see http://clockmaker.jp/blog/2008/08/papervision3d_focus_blur/
* @see http://wonderfl.net/code/d22f0f92eb9390b6f6ef84b808ab923f2e467137
* @author paq89
*/
[SWF(width=465, height=465, backgroundColor=0x001122, frameRate=60)]
public class Main extends ReflectionView
{
private var _container:DisplayObject3D;
private var _emitter:PlaneEmitter;
//private var _particlesList:Array = [];
private var _blurFilter:Array = [];
/**
* コンストラクタ
*/
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
/**
* ...
*/
private function init():void
{
// PV3D
_container = new DisplayObject3D();
scene.addChild(_container);
opaqueBackground = 0x001122;
// カメラ
camera.zoom = 2;
camera.focus = 200;
// 反射のアルファ
viewportReflection.alpha = 0.5;
// 軽量化のため、フィルターをあらかじめ作っておく
for (var i:int = 0; i < 20; i++)
{
_blurFilter[i] = new BlurFilter(i, i, 1);
}
// パーティクルシステムの構築
//_emitter = new PlaneEmitter(new SteadyClock(0.1), _particlesList);
_emitter = new PlaneEmitter(new SteadyClock(0.1));
var renderer:PV3DDisplayObject3DRenderer = new PV3DDisplayObject3DRenderer(_container);
renderer.addEmitter(_emitter);
// イベントリスナー
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
/**
* エンターフレームイベント
*/
private function onEnterFrame(e:Event):void
{
// エミッター更新
_emitter.step();
// Papervision3Dのレンダリング
singleRender();
// 被写界深度
setBlur();
}
/**
* マウスの位置に合わせてカメラを移動
*/
private function onMouseMove(e:MouseEvent):void
{
camera.x += (2000 * Math.sin(mouseX / stage.stageWidth * 360 * Math.PI / 180) - camera.x) * .1;
camera.z += (2000 * Math.cos(mouseX / stage.stageWidth * 360 * Math.PI / 180) - camera.z) * .1;
camera.y += (2000 * mouseY / stage.stageHeight - camera.y) * .1;
}
/**
* 被写界深度
*/
private function setBlur():void
{
//var len:int = _particlesList.length;
var iter:ParticleIterator = _emitter.getParticles().getIterator();
var p:Particle;
while (p = iter.particle) {
var o:DisplayObject3D = p.target;
if (!o.visible) o.visible = true;
// 距離の算出
var deg:Number = Math.abs(calcPointDistanceFromCamera(o) - 2000);
// ぼかしの適用値
var blurVal:int = Math.min(20, deg * 0.008 << 1 ) >> 0;;
if (blurVal > 19) blurVal = 19;
var blurFilter:BlurFilter = _blurFilter[blurVal];
// フィルター適用
o.filters = [blurFilter];
iter.next();
}
}
/**
* カメラからの距離を算出します
* @param obj 計測したいオブジェクト
* @return カメラからの距離(3D空間内のpx値)
*/
private function calcPointDistanceFromCamera(obj:DisplayObject3D):Number
{
var vecX:Number = obj.sceneX - camera.x;
var vecY:Number = obj.sceneY - camera.y;
var vecZ:Number = obj.sceneZ - camera.z;
return Math.sqrt((vecX * vecX) + (vecY * vecY) + (vecZ * vecZ));
}
}
}
//------------------------------------------------------------------------------------------------
import frocessing.color.ColorHSV;
import idv.cjcat.stardust.common.actions.Age;
import idv.cjcat.stardust.common.actions.CompositeAction;
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.initializers.Life;
import idv.cjcat.stardust.common.initializers.Scale;
import idv.cjcat.stardust.common.math.UniformRandom;
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.DisplayObjectClass3D;
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.zones.SinglePoint3D;
import idv.cjcat.stardust.threeD.zones.SphereCap;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.objects.primitives.Plane;
//------------------------------------------------------------------------------------------------
/**
* プレーンをひたすら出し続けるEmitter
*
* @author paq89
*/
class PlaneEmitter extends Emitter3D
{
public function PlaneEmitter(clock:Clock)
{
super(clock);
var doc3D:DisplayObjectClass3D = new DisplayObjectClass3D();
doc3D.displayObjectClass = PlaneParticle;
doc3D.constructorParams = [null, 100, 100, 1, 1];
var cap:SphereCap = new SphereCap(0, 0, 0, 50, 50, 15);
cap.rotationX = 180;
var rotationRand:UniformRandom = new UniformRandom(0, 180);
var omegaRand:UniformRandom = new UniformRandom(0, 4);
// パーティクルの属性を定義
addInitializer(doc3D);
addInitializer(new Life(new UniformRandom(200, 0)));
addInitializer(new Scale(new UniformRandom(1, 1.2)));
addInitializer(new Position3D(new SinglePoint3D(0, 0, 0)));
addInitializer(new Velocity3D(cap));
addInitializer(new Rotation3D(rotationRand, rotationRand, rotationRand));
addInitializer(new Omega3D(omegaRand, omegaRand, omegaRand));
// 重力を定義
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, 90, 0, 0, 1, 0));
// パーティクルのアクションを定義
addAction(gravity);
addAction(deflect);
addAction(new Age());
addAction(new DeathLife());
addAction(new Move3D());
addAction(new Spin3D());
addAction(new ScaleCurve(5, 20));
}
}
class PlaneParticle extends Plane
{
static private var col:int = 180;
public function PlaneParticle(material:MaterialObject3D = null, width:Number = 0, height:Number = 0, segmentsW:Number = 0, segmentsH:Number = 0):void
{
var color:ColorHSV = new ColorHSV(col += 2, 0.8);
// マテリアルを作成
var mat:WireframeMaterial = new WireframeMaterial(color.value);
mat.doubleSided = true;
super(mat, width, height, segmentsW, segmentsH);
useOwnContainer = true;
//if (particlesList){ particlesList.push(this); visible = false;}
}
}