25 Mar 2009 ActionScript Processing "FireCube" example ported to ActionScript 3.0 Tweet Processing example FireCube is so interesting to me. I ported it to ActionScript 3.0. The result is... Performance improvement Processing version calculates every pixel color when creating noise, combining values from adjacent pixels and converting color. So I implement it as follows: creating noise -> BitmapData.noise() combining values from adjacent pixels -> ConvolutionFilter converting color -> BitmapData.paletteMap() Difficulty HSV color space is not supported in AS3! I created a function called HSVtoRGB. Drawing a cube was a pain. So, I changed a cube to circle... Here is the code: (83 lines) // Processing FireCube (AS3 version) // original source: http://processing.org/learning/topics/firecube.html package { import flash.display.*; import flash.filters.*; import flash.geom.*; public class FireCube extends Sprite{ private const WIDTH:int = 200; private const HEIGHT:int = 150; public function FireCube(){ stage.align = "TL"; stage.scaleMode = "noScale"; scaleX = scaleY = 2; // Create circle var circle:Sprite = new Sprite(); circle.graphics.beginFill(0x808080); circle.graphics.drawCircle(0, 0, 10); circle.graphics.endFill(); // Create buffered image var fire:BitmapData = new BitmapData(WIDTH, HEIGHT, false, 0); var pg:BitmapData = fire.clone(); var noiseBmd:BitmapData = new BitmapData(WIDTH, 1); var bmp:Bitmap = new Bitmap(pg); addChild(bmp); // Generate the palette var r:Array = [], g:Array = [], b:Array = []; for(var x:int = 0; x < 256; x++) { //Hue goes from 0 to 85: red to yellow //Saturation is always the maximum: 255 //Lightness is 0..255 for x=0..128, and 255 for x=128..255 HSVtoRGB(x / 3, 1, Math.min(x * 3 / 255.0, 1), r, g, b); } // Use ConvolutionFilter to calculate for every pixel var filter:ConvolutionFilter = new ConvolutionFilter(3, 3, [0, 0, 0, 16, 16, 16, 0, 16, 0], 65); // Prepare points and matrix var matrix:Matrix = new Matrix(); var pt0:Point = new Point(0, HEIGHT - 1); var pt1:Point = new Point(0, -1); var pt2:Point = new Point(0, 1); // Do loop addEventListener("enterFrame", function(event:*):void{ // Randomize the bottom row of the fire buffer noiseBmd.noise(Math.random() * 0xffffffff, 0, 190, 7, true); fire.copyPixels(noiseBmd, noiseBmd.rect, pt0); // Display circle matrix.tx = mouseX; matrix.ty = mouseY; fire.draw(circle, matrix); // Add pixel values around current pixel fire.applyFilter(fire, fire.rect, pt1, filter); // Output everything to screen using our palette colors pg.paletteMap(fire, fire.rect, pt2, r, g, b); }); } // AS3 does not natively support HSV... :-( private function HSVtoRGB(h:int, s:Number, v:Number, r:Array, g:Array, b:Array):void { if (h < 60) { r.push((v * 255) << 16); g.push((v * (1 - (1 - h / 60.0) * s) * 255) << 8) b.push(v * (1 - s) * 255); } else if (h < 120) { r.push((v * (1 - (-h / 60.0 - 1) * s) * 255) << 16); g.push((v * 255) << 8); b.push(v * (1 - s) * 255); } else { throw Error('not implemented'); } } } }