package { import flash.display.*; import flash.events.*; 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 net.hires.debug.Stats; /** * スターダストを使った、3Dパーティクルデモ * @author yasu */ [SWF(width=465, height=465, frameRate=60)] public class Main extends BasicView { // コンストラクタ public function Main() { // 3Dのパーツを配置 scene.addChild(particles); earth.rotationX = 90; scene.addChild(earth); scene.addChild(sphere); // パーティクルシステムの構築 emitter = new MyEmitter(new SteadyClock(3)); // エミッターに1フレームに発生させたい数値を指定 particleRenderer = new PV3DParticleRenderer(particles); particleRenderer.addEmitter(emitter); // エンターフレームイベントの登録 addEventListener(Event.ENTER_FRAME, loop); // 背景 opaqueBackground = 0x0; stage.quality = StageQuality.MEDIUM; //画質を低に addChild(new Stats); } // 地面 private var earth:Plane = new Plane(new WireframeMaterial(0x999999, .5), 5000, 5000, 12, 12); // エミッター private var emitter:Emitter; // レンダラー private var particleRenderer:Renderer; // パーティクルのラッパー private var particles:Particles = new Particles(); //モーションの角度 private var rot:Number = 0; //球体 private var sphere:Sphere = new Sphere(new WireframeMaterial(0xFF99FF), 10, 4, 4); // エンターフレームイベント 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); // パーティクルの発生源と球体の位置を揃える sphere.x = MyEmitter(emitter).point.x; sphere.y = MyEmitter(emitter).point.y; sphere.z = MyEmitter(emitter).point.z; // パーティクルの方向を変える 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(); } } } import idv.cjcat.stardust.common.actions.Age; import idv.cjcat.stardust.common.actions.DeathLife; 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(0xFF99FF, 1, 1, 5); // パーティクルの属性を定義 addInitializer(new Position3D(point)); // 発生位置 addInitializer(new PV3DParticle([mat])); addInitializer(new Life(new UniformRandom(100, 0))); addInitializer(new Velocity3D(sphereCap)); // パーティクルのアクションを定義 addAction(new Age()); // 寿命を有効化 addAction(new DeathLife()); // 消えるを有効化 addAction(new Accelerate3D(0.05)); // 加速を有効化 addAction(new Move3D()); // 移動を有効化 } } [Stardust] 3Dオブジェクトの軌道にパーティクルをつける