package; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix3D; import flash.geom.Vector3D; import flash.utils.ByteArray; import flash.utils.Endian; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; class OneMillion extends Sprite { // storage params private static inline var WIDTH : Int = 550; private static inline var HEIGHT : Int = 400; private static inline var PIXELS : Int = WIDTH*HEIGHT; private static inline var PIXEL_BYTES : Int = PIXELS*4; private static inline var PARTICLE_START : Int = PIXEL_BYTES; private static inline var PARTICLES : Int = 0x400 * 1000; private static inline var PARTICLE_BYTES : Int = PARTICLES*12; private static inline var DATA_START : Int = PARTICLE_START + PARTICLE_BYTES; private static inline var _x : Int = DATA_START+4; private static inline var _y : Int = _x+4; private static inline var _z : Int = _y+4; private static inline var _mx : Int = _z+4; private static inline var _my : Int = _mx+4; private static inline var _mz : Int = _my+4; private static inline var _a : Int = _mz+4; private static inline var _f : Int = _a+4; private static inline var _b : Int = _f+4; private static inline var _d : Int = _b+4; private static inline var _g : Int = _d+4; private static inline var _o : Int = _g+4; private static inline var _ox : Int = _o+4; private static inline var _oy : Int = _ox+4; private static inline var _oz : Int = _oy+4; private static inline var _tx : Int = _oz+4; private static inline var _ty : Int = _tx+4; private static inline var p00: Int = _ty+4; private static inline var p01: Int = p00+4; private static inline var p02: Int = p01+4; private static inline var p10: Int = p02+4; private static inline var p11: Int = p10+4; private static inline var p12: Int = p11+4; private static inline var p20: Int = p12+4; private static inline var p21: Int = p20+4; private static inline var p22: Int = p21+4; private static inline var p32: Int = p22+4; private static inline var pz: Int = p32+4; private static inline var _w: Int = pz+4; private static inline var DATA_END : Int = _w + 4; private static inline var BYTES : Int = DATA_END; // class constants private static inline var SCALE : Int = 40; private static inline var FOCAL : Float = 433.0126953125; private static inline var CX : Int = Std.int(WIDTH/2); private static inline var CY : Int = Std.int(HEIGHT/2); private static inline var SHADE : Int = 0x050505; private static inline var MAXCOLOR : Int = 0xFFFFFF - SHADE; // instance properties private var bitmap : Bitmap; private var bitmapData : BitmapData; private var _matrix : Matrix3D; function init():Void { initBuffers(); generateVertices(); layout(); addEventListener( Event.ENTER_FRAME, enterFrameHandler ); } function layout() : Void { var tf : TextFormat = new TextFormat(); tf.font = 'arial'; tf.size = 10; tf.color = 0xffffff; var textField: TextField = new TextField(); textField.autoSize = TextFieldAutoSize.LEFT; textField.defaultTextFormat = tf; textField.selectable = false; textField.text = 'nathan at webr3 dot org : Pushing ' + PARTICLES + ' particles - pure haXe.'; textField.y = 400 - textField.height; textField.opaqueBackground = 0x000000; addChild( textField ); } function initBuffers():Void { // create bitmap this.bitmapData = new BitmapData( WIDTH , HEIGHT , false , 0 ); this.bitmap = new Bitmap( this.bitmapData ); addChild( this.bitmap ); // create memory var storage : ByteArray = new ByteArray(); storage.endian = Endian.LITTLE_ENDIAN; storage.length = BYTES; flash.Memory.select( storage ); // starting positions flash.Memory.setFloat( _x, 1 ); flash.Memory.setFloat( _y, 1 ); flash.Memory.setFloat( _z, 1 ); flash.Memory.setFloat( _mx, 0 ); flash.Memory.setFloat( _my, 0 ); flash.Memory.setFloat( _mz, 0 ); // lorenz values flash.Memory.setFloat( _a , 1.111); flash.Memory.setFloat( _b , 1.479); flash.Memory.setFloat( _f , 4.494); flash.Memory.setFloat( _g , 0.44); flash.Memory.setFloat( _d , 0.135); flash.Memory.setFloat( _tx , 0); flash.Memory.setFloat( _ty , 0); // start matrix _matrix = new Matrix3D(); } function generateVertices():Void { var a : Int = 0; while( a < PARTICLES ) { flash.Memory.setI32( _o , PARTICLE_START + (a*12) ); flash.Memory.setFloat( _mx , flash.Memory.getFloat(_x) + flash.Memory.getFloat(_d) * (-flash.Memory.getFloat(_a) * flash.Memory.getFloat(_x) - flash.Memory.getFloat(_y) * flash.Memory.getFloat(_y) - flash.Memory.getFloat(_z) * flash.Memory.getFloat(_z) + flash.Memory.getFloat(_a) * flash.Memory.getFloat(_f)) ); flash.Memory.setFloat( _my , flash.Memory.getFloat(_y) + flash.Memory.getFloat(_d) * (-flash.Memory.getFloat(_y) + flash.Memory.getFloat(_x) * flash.Memory.getFloat(_y) - flash.Memory.getFloat(_b) * flash.Memory.getFloat(_x) * flash.Memory.getFloat(_z) + flash.Memory.getFloat(_g)) ); flash.Memory.setFloat( _mz , flash.Memory.getFloat(_z) + flash.Memory.getFloat(_d) * (-flash.Memory.getFloat(_z) + flash.Memory.getFloat(_b) * flash.Memory.getFloat(_x) * flash.Memory.getFloat(_y) + flash.Memory.getFloat(_x) * flash.Memory.getFloat(_z)) ); flash.Memory.setFloat( _x , flash.Memory.getFloat(_mx) ); flash.Memory.setFloat( _y , flash.Memory.getFloat(_my) ); flash.Memory.setFloat( _z , flash.Memory.getFloat(_mz) ); flash.Memory.setI32( flash.Memory.getI32(_o) , Std.int( flash.Memory.getFloat(_x)*SCALE ) ); flash.Memory.setI32( flash.Memory.getI32(_o)+4 , Std.int( flash.Memory.getFloat(_y)*SCALE ) ); flash.Memory.setI32( flash.Memory.getI32(_o)+8 , Std.int( flash.Memory.getFloat(_z)*SCALE ) ); a++; } } static inline function updateMatrix( matrix : Matrix3D , mx : Float , my : Float ) : Void { flash.Memory.setFloat( _tx , flash.Memory.getFloat(_tx) + ((mx - flash.Memory.getFloat(_tx))/10) ); flash.Memory.setFloat( _ty , flash.Memory.getFloat(_ty) + ((my - flash.Memory.getFloat(_ty))/10) ); matrix.identity(); matrix.appendRotation( flash.Memory.getFloat(_tx), Vector3D.Y_AXIS ); matrix.appendRotation( flash.Memory.getFloat(_ty), Vector3D.X_AXIS ); matrix.appendTranslation( 0, 0, 10 ); flash.Memory.setFloat( p00 , matrix.rawData[ 0x0 ] ); flash.Memory.setFloat( p01 , matrix.rawData[ 0x1 ] ); flash.Memory.setFloat( p02 , matrix.rawData[ 0x2 ] ); flash.Memory.setFloat( p10 , matrix.rawData[ 0x4 ] ); flash.Memory.setFloat( p11 , matrix.rawData[ 0x5 ] ); flash.Memory.setFloat( p12 , matrix.rawData[ 0x6 ] ); flash.Memory.setFloat( p20 , matrix.rawData[ 0x8 ] ); flash.Memory.setFloat( p21 , matrix.rawData[ 0x9 ] ); flash.Memory.setFloat( p22 , matrix.rawData[ 0xa ] ); flash.Memory.setFloat( p32 , matrix.rawData[ 0xe ] ); } private function enterFrameHandler( event : Event ): Void { updateMatrix( _matrix , mouseX , mouseY ); var po : Int = 0; // clear all bitmap data for( i in 0...PIXELS ) { flash.Memory.setI32( i*4 , 0 ); } for( a in 0...PARTICLES ) { setPositions( PARTICLE_START + (a*12) ); if( setPZ() > 0 ) { po = pointToOffset( Std.int( flash.Memory.getFloat(_w) * ( flash.Memory.getI32( flash.Memory.getI32(_ox) ) * flash.Memory.getFloat( p00 ) + flash.Memory.getI32( flash.Memory.getI32(_oy) ) * flash.Memory.getFloat( p10 ) + flash.Memory.getI32( flash.Memory.getI32(_oz) ) * flash.Memory.getFloat( p20 ) ) + CX ), Std.int( flash.Memory.getFloat(_w) * ( flash.Memory.getI32( flash.Memory.getI32(_ox) ) * flash.Memory.getFloat( p01 ) + flash.Memory.getI32( flash.Memory.getI32(_oy) ) * flash.Memory.getFloat( p11 ) + flash.Memory.getI32( flash.Memory.getI32(_oz) ) * flash.Memory.getFloat( p21 ) ) + CY ), WIDTH ); if( po < PIXEL_BYTES && 0 < po ) { flash.Memory.setI32( po , increaseColor( flash.Memory.getI32(po) ) ); } } } // update display flash.system.ApplicationDomain.currentDomain.domainMemory.position = 0; this.bitmapData.lock(); this.bitmapData.setPixels( this.bitmapData.rect , flash.system.ApplicationDomain.currentDomain.domainMemory ); this.bitmapData.unlock( this.bitmapData.rect ); } static inline function setPositions( o : Int ) : Void { flash.Memory.setI32( _ox , o ); flash.Memory.setI32( _oy , o+4 ); flash.Memory.setI32( _oz , o+8 ); } static inline function setPZ() : Float { flash.Memory.setFloat( pz , FOCAL + flash.Memory.getI32( flash.Memory.getI32(_ox) ) * flash.Memory.getFloat( p02 ) + flash.Memory.getI32( flash.Memory.getI32(_oy) ) * flash.Memory.getFloat( p12 ) + flash.Memory.getI32( flash.Memory.getI32(_oz) ) * flash.Memory.getFloat( p22 ) + flash.Memory.getFloat( p32 ) ); flash.Memory.setFloat( _w , FOCAL / flash.Memory.getFloat(pz) ); return flash.Memory.getFloat(pz); } static inline function increaseColor( c : UInt ) : UInt { return c >= MAXCOLOR ? 0xFFFFFF : c + SHADE; } static inline function pointToOffset( vx : Int , vy : Int , vw : Int ) : UInt { return (( (vy-1) * vw ) + vx-1) * 4; } function new() { super(); init(); } static function main() { var mc:flash.display.MovieClip = flash.Lib.current; var main:OneMillion = new OneMillion(); mc.addChild( main ); } }