package { import flash.display.*; import flash.geom.* import flash.media.*; import flash.events.*; import flash.utils.*; import flash.net.*; import flash.filters.*; import flash.text.*; import flash.system.SecurityPanel; import flash.system.Security; public class camObj extends Sprite { private var cam : Camera; private var vid : Video; private var scaleFactor : Number; private var scaledXY : Point; private var transMatrix : Matrix; private var transColor : ColorTransform; private var refRect : Rectangle; private var refPoint : Point; private var current : BitmapData; private var before : BitmapData; private var output : Bitmap; private var photoLoader : Loader; private var particleObj : Object; private var speedXY : Number = 1.00; private var speedR : Number = 1.00; private var friction : Number = 0.25; public var devMode : Boolean = true; public function camObj() { // Retrieve camera feed cam = Camera.getCamera(); // Initialize camera. If it's disabled, prompt user for permission if (!cam) { Security.showSettings(SecurityPanel.PRIVACY); } else if (cam.muted) { Security.showSettings(SecurityPanel.PRIVACY); cam.addEventListener(StatusEvent.STATUS, statusHandler); } else { initCamera(); } } private function statusHandler(event:StatusEvent):void { if (event.code == "Camera.Unmuted") { initCamera(); cam.removeEventListener(StatusEvent.STATUS, statusHandler); } } public function initCamera():void { // Load camera feed into video object vid = new Video(cam.width, cam.height); vid.attachCamera(cam); // Initialize camera feed vars scaleFactor = stage.stageWidth / cam.width; scaledXY = new Point(); scaledXY.x = int(cam.width * scaleFactor); scaledXY.y = int(cam.height * scaleFactor); transColor = new ColorTransform(); refRect = new Rectangle(0, 0, scaledXY.x, scaledXY.y); refPoint = new Point(0, 0); current = new BitmapData(scaledXY.x, scaledXY.y); before = new BitmapData(scaledXY.x, scaledXY.y); // Initialize transformation matrix transMatrix = new Matrix(); transMatrix.scale(scaleFactor, scaleFactor); // Initialize motion map output = new Bitmap(); output.x = refPoint.x; output.y = refPoint.y; // DEV MODE: display stats and raw camera feed (160x120) if (devMode == true) { var debugText:TextField = new TextField(); var format:TextFormat = new TextFormat(); debugText.text = "DEV MODE" + "\n" + "Camera Max FPS: " + cam.fps + "\n" + "Sample Size: " + cam.width + "x" + cam.height; debugText.autoSize = TextFieldAutoSize.LEFT; format.font = "Courier New"; format.size = 12; format.bold = true; format.color = "0xffffff"; debugText.setTextFormat(format); vid.x = 10; vid.y = 10; debugText.x = 10; debugText.y = 15 + vid.height; addChild(output); addChild(vid); addChild(debugText); } particleObj = new Object(); particleObj.layer = new Array(); particleObj.objs = new Array(); particleObj.attrb = new Object(); particleObj.attrb.pCount = new Array(200, 200, 30, 10, 10, 10); particleObj.attrb.pScale = new Array(0.02, 0.04, 0.06, 0.08, 0.10, 0.12); particleObj.attrb.pBlur = new Array(90, 70, 50, 16, 8, 4); // Load image from file, call handler when ready photoLoader = new Loader(); photoLoader.contentLoaderInfo.addEventListener(Event.INIT, initHandler); photoLoader.load(new URLRequest("pic.png")); // Update screen every 50ms setInterval(spectraUpdate,50); } private function initHandler(event:Event):void { // Initialize layers of particles for(var i:int = 0; i < particleObj.attrb.pCount.length; i++) { drawParticles(particleObj.attrb.pCount[i], particleObj.attrb.pScale[i], particleObj.attrb.pBlur[i]); } } public function drawParticles(num:int, size:Number, blurAmt:int) { // Get particle image data var imgData:BitmapData = Bitmap(photoLoader.content).bitmapData; // Make scratch copy var imgRend:BitmapData = imgData.clone(); // If set, apply a blur filter var blurFilter:BlurFilter = new BlurFilter(blurAmt, blurAmt); if (blurAmt > 0) { imgRend.applyFilter(imgRend, imgRend.rect, new Point(0,0), blurFilter); } // Make layer container var pSlice:MovieClip = new MovieClip(); particleObj.layer.push(pSlice); for (var i:int = 0; i < num; i++) { // Create instance of image data var img:Bitmap = new Bitmap(imgRend); // Scale to designated size img.width = img.width * size; img.height = img.height * size; // Put bitmap into movie clip var instance:MovieClip = new MovieClip(); instance.addChild(img); instance.width = img.width; instance.height = img.height; // Randomly place instance and assign vector instance.x = Math.random() * stage.stageWidth; instance.y = Math.random() * stage.stageHeight; instance.rotation = Math.random() * 360; instance.v = new Point(((Math.random()*speedXY)-(speedXY/2)),((Math.random()*speedXY)-(speedXY/2))); instance.f = new Point(0,0); instance.acl = new Point(0,0); instance.rot = (Math.random() * speedR) - 1; particleObj.objs.push(instance); // Add to layer container pSlice.addChild(instance); } // Add container to stage addChild(pSlice); } public function spectraUpdate():void { // Take a snapshot from the video object, scaled to scaleFactor current.draw(vid, transMatrix); // Combine with previous snapshot using difference filter, scaled to scaleFactor current.draw(before, transMatrix, transColor, 'difference'); // Generate monochromatic motion map of color 0xFF1111 current.threshold(current, refRect, refPoint, '>', 0xff111111, 0xffff0000); // Save current snapshot for next iteration before.draw(vid); // Display current map output.bitmapData = current; // Move particles particleUpdate(); } public function particleUpdate():void { var objCount:int = 0; var thisParticle = new Object(); // Iterate through layers for (var layerIndex:int = 0; layerIndex < particleObj.layer.length; layerIndex++) { objCount += particleObj.attrb.pCount[layerIndex]; // Iterate through particles for (var objIndex:int = 0; objIndex < objCount; objIndex++) { thisParticle = particleObj.objs[objIndex]; /************* "Relocate" collision method // If center of particle is intersected by motion map, move it and set acceleration if (output.bitmapData.getPixel(thisParticle.x, thisParticle.y) > 0x100000) { do { if (thisParticle.v.x > 0) thisParticle.x = thisParticle.x - 1; else thisParticle.x = thisParticle.x + 1; if (thisParticle.v.y > 0) thisParticle.y = thisParticle.y - 1; else thisParticle.y = thisParticle.y + 1; } while(output.bitmapData.getPixel(thisParticle.x, thisParticle.y) > 0x100000); thisParticle.v.x = thisParticle.v.x * -1; thisParticle.v.y = thisParticle.v.y * -1; } // Calculate friction if (thisParticle.v.x > speedXY) thisParticle.f.x = friction; else if (thisParticle.v.x < -speedXY) thisParticle.f.x = friction * -1; else thisParticle.f.x = 0; if (thisParticle.v.y > speedXY) thisParticle.f.y = friction; else if (thisParticle.v.y < -speedXY) thisParticle.f.y = friction * -1; else thisParticle.f.y = 0; // Calculate velocity thisParticle.v.x += thisParticle.acl.x - thisParticle.f.x; thisParticle.v.y += thisParticle.acl.y - thisParticle.f.y; // If at edge of screen, relocate if (thisParticle.x < -thisParticle.width) { thisParticle.x = stage.stageWidth + thisParticle.width; } else if (thisParticle.x > stage.stageWidth + thisParticle.width) { thisParticle.x = -thisParticle.width; } if (thisParticle.y < -thisParticle.height) { thisParticle.y = stage.stageHeight + thisParticle.height; } else if (thisParticle.y > stage.stageHeight + thisParticle.height) { thisParticle.y = -thisParticle.height; } // Move particle thisParticle.x += thisParticle.v.x; thisParticle.y += thisParticle.v.y; */ /************** "Fly and Ignore" collision method */ if (thisParticle.ignCount > 0) flight(thisParticle); else { // If center of particle is intersected by motion map, make it fly and set ignore count if (output.bitmapData.getPixel(thisParticle.x, thisParticle.y) > 0x100000) { thisParticle.ignCount = 10; flight(thisParticle); } // Otherwise, just move it else { // Calculate friction if (thisParticle.v.x > speedXY) thisParticle.f.x = friction; else if (thisParticle.v.x < -speedXY) thisParticle.f.x = friction * -1; else thisParticle.f.x = 0; if (thisParticle.v.y > speedXY) thisParticle.f.y = friction; else if (thisParticle.v.y < -speedXY) thisParticle.f.y = friction * -1; else thisParticle.f.y = 0; // Calculate velocity thisParticle.v.x += thisParticle.acl.x - thisParticle.f.x; thisParticle.v.y += thisParticle.acl.y - thisParticle.f.y; // If at edge of screen, relocate if (thisParticle.x < -thisParticle.width) { thisParticle.x = stage.stageWidth + thisParticle.width; } else if (thisParticle.x > stage.stageWidth + thisParticle.width) { thisParticle.x = -thisParticle.width; } if (thisParticle.y < -thisParticle.height) { thisParticle.y = stage.stageHeight + thisParticle.height; } else if (thisParticle.y > stage.stageHeight + thisParticle.height) { thisParticle.y = -thisParticle.height; } // Move particle thisParticle.x += thisParticle.v.x; thisParticle.y += thisParticle.v.y; thisParticle.rotation += speedR; } } } } } private function flight(particle:Object):void { if (particle.v.x > 0) particle.x += speedXY * (particle.ignCount / 2); else particle.x -= speedXY * (particle.ignCount / 2); if (particle.v.y > 0) particle.y += speedXY * (particle.ignCount / 2); else particle.y -= speedXY * (particle.ignCount / 2); particle.rotation += speedR; particle.ignCount--; } } }