package { import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.Event; import flash.filters.BlurFilter; import org.papervision3d.cameras.Camera3D; import org.papervision3d.core.math.Number3D; import org.papervision3d.core.proto.CameraObject3D; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.BasicView; import org.papervision3d.cameras.CameraType; import gs.TweenLite; import gs.OverwriteManager; import org.papervision3d.view.layer.ViewportLayer; import it.flashfuck.debugger.FPSMonitor; /** * ... * @author John del Rosario * @version 1.0 */ public class Main extends Sprite { private var view:BasicView; private var particles:Vector.; private var layers:Vector.; private var environment:Cube; private var origin:Sphere; private var _quantity:int; private var _environmentSize:Number; private var _highBound:Number; private var _lowBound:Number; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point _quantity = 30; OverwriteManager.init(3); init2d(); initView(); initEnvironment(); initParticles(); addEventListener(Event.ENTER_FRAME, mainLoop, false, 0, true); } /** * initialize all 2d overlays */ private function init2d():void { addChild(new FPSMonitor()); } /** * create BasicView instance, and create a dummy object as the origin for the camera to look at. */ private function initView():void { view = new BasicView(640, 480, true, true, CameraType.FREE); origin = new Sphere(new WireframeMaterial(), 10); origin.x = 0; origin.y = 0; origin.z = 0; view.camera.x = 0; view.camera.y = 0; view.camera.z = 0; view.camera.fov = 63; view.viewport.interactive = true; addChild(view); } /** * create the environment (a cube) for the particles to exist. */ private function initEnvironment():void { _environmentSize = view.width; var mat:WireframeMaterial = new WireframeMaterial(0xCCCCCC, 30, 1); mat.name = "all"; var matList:MaterialsList = new MaterialsList( {all:mat } ); environment = new Cube(matList, _environmentSize, _environmentSize, _environmentSize); view.scene.addChild(environment); //set boundaries _highBound = _environmentSize / 2; _lowBound = -_environmentSize / 2; } /** * Create the particles according to _quantity. * Give them random coordinates within their environment. * Put them in their own layer for effects. */ private function initParticles():void { particles = new Vector.(); layers = new Vector.(); for (var i:int = 0; i < _quantity; i++) { var mat:ColorMaterial = new ColorMaterial(0xFFFFFF, 1, true); var particle:Sphere = new Sphere(mat, 10); var x:Number = Math.random() * (_highBound - _lowBound) + _lowBound; var y:Number = Math.random() * (_highBound - _lowBound) + _lowBound; var z:Number = Math.random() * (_highBound - _lowBound) + _lowBound; particle.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, glow, false, 0, true); particle.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, revert, false, 0, true); particle.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, particle_clicked, false, 0, true); particle.x = x; particle.y = y; particle.z = z; particles.push(particle); environment.addChild(particle); //apply layer to particles for filters var particleLayer:ViewportLayer = view.viewport.getChildLayer(particles[i], true); layers.push(particleLayer); } //make them float float(); } /** * Main movie loop * @param e */ private function mainLoop(e:Event):void { view.camera.pitch((mouseY-(stage.stageHeight/2))/(stage.height/2)*2); view.camera.yaw((mouseX - (stage.stageWidth/2))/(stage.width / 2) * 2); depth_of_field(); view.singleRender(); } /** * simulates depth of field effect */ private function depth_of_field():void { var cam:CameraObject3D = view.camera; for (var i:int = 0; i < particles.length; i++) { //get Z distance between particle and camera var dZ:Number = particles[i].distanceTo(cam); var blurValue:Number = Math.abs(3 * (dZ / 100)); //apply filter to particle's layer var blur:BlurFilter = new BlurFilter(blurValue, blurValue, 2); particles[i].container.filters = [blur]; particles[i].container.alpha = 0.1 + (blurValue * 2 * .1); } } /** * makes the particles float */ private function float():void { for (var i:Number = 0; i < particles.length ; i ++) { floatThis(particles[i]); } } /** * floats one particle * @param object : target object to float */ private function floatThis(object:DisplayObject3D):void { var targ:DisplayObject3D = new DisplayObject3D(); targ.x = Math.random() * (_highBound - _lowBound) + _lowBound; targ.y = Math.random() * (_highBound - _lowBound) + _lowBound; targ.z = Math.random() * (_highBound - _lowBound) + _lowBound; var time:Number = object.distanceTo(targ) / 10; TweenLite.killTweensOf(object, true); TweenLite.to(object, time, { x: targ.x, y: targ.y, z: targ.z, onComplete:floatThis, onCompleteParams:[object]} ); } private function glow(e:InteractiveScene3DEvent):void { var targ:Sphere = e.target as Sphere; TweenLite.to(targ, 1, {scale: 3 } ); } private function revert(e:InteractiveScene3DEvent):void { var targ:Sphere = e.target as Sphere; TweenLite.to(targ, 1, {scale: 1, onComplete:floatThis, onCompleteParams:[e.target] } ); } private function particle_clicked(e:InteractiveScene3DEvent):void { var targ:Sphere = e.target as Sphere; var coords:Number3D = new Number3D(targ.x, targ.y, targ.z); //show all particles again when moving to another one for (var i:int = 0; i < particles.length; i++) { particles[i].visible = true; } TweenLite.to(view.camera, 1, { x:coords.x, y:coords.y, z:coords.z, onUpdate:onUpdate_function, onComplete: hideParticle, onCompleteParams: [targ] } ); } private function onUpdate_function():void { view.camera.lookAt(origin); } /** * hide the particle being moved to to prevent rendering issues when the camera is inside it * @param object : target object to hide */ private function hideParticle(object:DisplayObject3D):void { object.visible = false; } } }