package { import flash.display.*; import flash.events.*; import flash.geom.Matrix; import idv.cjcat.stardust.common.clocks.SteadyClock; import idv.cjcat.stardust.common.emitters.Emitter; import idv.cjcat.stardust.common.renderers.Renderer; import idv.cjcat.stardust.threeD.papervision3d.renderers.PV3DParticleRenderer; import org.papervision3d.core.geom.Particles; import org.papervision3d.core.math.Number3D; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.primitives.*; import org.papervision3d.view.BasicView; import org.papervision3d.view.layer.ViewportLayer; import net.hires.debug.*; /** * スターダストを使った、3Dパーティクルデモ * 詳細はこちらを参考ください * http://clockmaker.jp/blog/2009/12/as3-stardust/ * @author yasu */ [SWF(width=465, height=465, frameRate=60)] public class KiraKiraParticle extends BasicView { // コンストラクタ public function KiraKiraParticle() { // PV3Dのパーティクル particles = new Particles(); // ビューポートレイヤーにすると、ビットマップデータの加工がやりやすいよ viewportLayerForParticle = particles.createViewportLayer(viewport); scene.addChild(particles); //地面 earth = new Plane(new WireframeMaterial(0x999999, .5), 5000, 5000, 6, 6) earth.y = -500; earth.rotationX = 90; scene.addChild(earth); // パーティクルシステムの構築 emitter = new MyEmitter(new SteadyClock(3)); // エミッターに1フレームに発生させたい数値を指定 particleRenderer = new PV3DParticleRenderer(particles); particleRenderer.addEmitter(emitter); // エンターフレームイベントの登録 addEventListener(Event.ENTER_FRAME, loop); // 背景 opaqueBackground = 0x0; stage.quality = StageQuality.LOW; //画質を低に // キラキラロジック canvas = new BitmapData(465 / 4, 465 / 4, false, 0x000000); var bmp:Bitmap = new Bitmap(canvas, PixelSnapping.NEVER, false); bmp.scaleX = bmp.scaleY = 4; bmp.smoothing = true; bmp.blendMode = BlendMode.ADD; addChild(bmp); mtx = new Matrix(); mtx.translate(-viewport.width / 2, -viewport.height / 2); mtx.scale(0.25, 0.25); mtx.translate(viewport.width / 4, viewport.height / 4); } // キラキラ private var canvas:BitmapData; // 地面 private var earth:Plane; // エミッター private var emitter:Emitter; // レンダラー private var particleRenderer:Renderer; // パーティクルのラッパー private var particles:Particles; //モーションの角度 private var rot:Number = 0; // ビューポート private var viewportLayerForParticle:ViewportLayer; // キラキラのキャプチャ変換行列 private var mtx:Matrix; // エンターフレームイベント private function loop(e:Event):void { rot += 3; // 円周上を動いているかのようにみせる MyEmitter(emitter).point.x = 400 * Math.sin(rot * Number3D.toRADIANS); MyEmitter(emitter).point.y = 300; MyEmitter(emitter).point.z = 300 * Math.cos(rot * Number3D.toRADIANS); // パーティクルの方向を変える MyEmitter(emitter).sphereCap.rotationX = 90; MyEmitter(emitter).sphereCap.rotationZ = -rot - 90; // カメラをマウス座標にする camera.x += (1000 * Math.sin(mouseX / stage.stageWidth * Math.PI * 2) - camera.x) * 0.1; camera.y += (600 * mouseY / stage.stageHeight - camera.y) * 0.1; camera.z += (1000 * Math.cos(mouseX / stage.stageWidth * Math.PI * 2) - camera.z) * 0.1; // エミッター更新 emitter.step(); // Papervision3Dのレンダリング singleRender(); // キラキラ canvas.fillRect(canvas.rect, 0x0); canvas.draw(viewportLayerForParticle, mtx); } } } import idv.cjcat.stardust.common.actions.Age; 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.math.UniformRandom; import idv.cjcat.stardust.threeD.actions.Accelerate3D; import idv.cjcat.stardust.threeD.actions.Move3D; import idv.cjcat.stardust.threeD.emitters.Emitter3D; import idv.cjcat.stardust.threeD.initializers.Position3D; import idv.cjcat.stardust.threeD.initializers.Velocity3D; import idv.cjcat.stardust.threeD.papervision3d.initializers.PV3DParticle; import idv.cjcat.stardust.threeD.zones.SinglePoint3D; import idv.cjcat.stardust.threeD.zones.SphereCap; import org.papervision3d.materials.special.ParticleMaterial; /** * カスタムエミッター * @author yasu */ class MyEmitter extends Emitter3D { public var point:SinglePoint3D = new SinglePoint3D(); // パーティクルの発生位置 public var sphereCap:SphereCap = new SphereCap(0, 0, 0, 1, 0, 40); // パーティクルの拡散 public function MyEmitter(clock:Clock = null) { super(clock); // マテリアル var mat:ParticleMaterial = new ParticleMaterial(0xFFCCBB, 1, 1, 6); // パーティクルの属性を定義 addInitializer(new Position3D(point)); // 発生位置 addInitializer(new PV3DParticle([mat])); addInitializer(new Life(new UniformRandom(120, 0))); addInitializer(new Velocity3D(sphereCap)); // パーティクルのアクションを定義 addAction(new Age()); // 寿命を有効化 addAction(new DeathLife()); // 消えるを有効化 addAction(new Accelerate3D(0.05)); // 加速を有効化 addAction(new Move3D()); // 移動を有効化 addAction(new ScaleCurve(20, 20)); //スケール変更を有効化 } } [Stardust] キラキラの3Dパーティクル