Papervision3D sliced Image-Cube with XML

Pfffft… not to have it rotten on my harddrive here my example of the modified sliced cube PV3D from John Lindquist. Here’s my code (making the „pile of crap“ even bigger :) package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.net.URLLoader; import flash.net.URLRequest; import flash.text.TextField; import mx.core.BitmapAsset;…

sliced cube3d

Pfffft… not to have it rotten on my harddrive here my example of the modified sliced cube PV3D from John Lindquist. Here’s my code (making the „pile of crap“ even bigger :)

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import mx.core.BitmapAsset;
	import src.holder;

	import gs.TweenMax;
	import gs.easing.Quad;

	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.objects.primitives.Plane;

	//[SWF(width="752", height="552", backgroundColor="0xffffff", frameRate="31")]
	public class SlicedCube extends BasicView
	{

		private var _cubeWidth:Number = 620;

		// vars
		private var mouseDownX:Number = 0;
		private var targetRotation:Number = 0;

		private var NUM_SLICES:int = 5;

		private var _offsetX:int = 30;
		private var _offsetY:int = 30;

		private var cubes:Array = [];
		private var _xml:XML;
		private var _xmlLoader:URLLoader;
		private var _xmlSource:String = '03_playlist.xml';
		private var _numSlides:int;							//	number of assets in XML
		private var _slideNum:int;							//	index pointer in _XML; starts with 3, because all sides are skinned in the first place
		private var _pictures:XMLList;

		private var _h:holder;								// TEMP MC for composition of image, text - changeSide
		private var _mcBottom:holder;
		private var _mcTop:holder;
		private var _mcBack:holder;
		private var _mcFront:holder;

		private var _matFront:Bitmap;
		private var _matTop:Bitmap;
		private var _matBack:Bitmap;
		private var _matBottom:Bitmap;

		private var _shownSide:Array = new Array("back", "bottom", "front", "top");
		private var _shownSidePointer:int = 0;
		private var _sideToSkin:String;

		public function SlicedCube()
		{
			//super(_cubeWidth, 752);

			//opaqueBackground = 0x000000;
			camera.focus = 100;
			camera.zoom = 10;
			camera.ortho = false;

			// init holder(s) with XML data
			// read XML
			// ...
			_xmlLoader = new URLLoader();
			_xmlLoader.load(new URLRequest(_xmlSource));
			_xmlLoader.addEventListener(Event.COMPLETE, processXML);

			// <---

		this.addEventListener( Event.ENTER_FRAME, onRenderTick );

			//skinCubes(h, "top");
			//scene.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
		}

		private function processXML(e:Event):void
		{

			_xml = new XML(e.currentTarget.data);
			_pictures = _xml.image;
			_numSlides = _pictures.length();
			_slideNum = 2;	// initially it's the 4th node, because the cube is skinned with 4 already

			// SKIN CUBE 1st time	--> start with BACK
			_mcBack = new holder(_pictures[0].@url, _pictures[0].title, _pictures[0].description);
			_mcBack.addEventListener(Event.COMPLETE, backLoader, false, 0, true);

		}

		private function createCubes():void
		{

			trace('CREATING CUBES');

			for(var i:int = 0; i < NUM_SLICES; i++)
			{
				var materialsList:MaterialsList = new MaterialsList();
				var sliceWidth:Number = _cubeWidth / NUM_SLICES;
				var sliceX:Number = sliceWidth * i;												

				materialsList.addMaterial(createSlicedBitmapMaterial(_matFront, sliceX, sliceWidth, true), "front");
				materialsList.addMaterial(createSlicedBitmapMaterial(_matBack, sliceX, sliceWidth), "back");
				materialsList.addMaterial(createSlicedBitmapMaterial(_matTop, sliceX, sliceWidth), "top");
				materialsList.addMaterial(createSlicedBitmapMaterial(_matBottom, sliceX, sliceWidth, true), "bottom");

				materialsList.addMaterial(new ColorMaterial(0xffffff), "right");
				materialsList.addMaterial(new ColorMaterial(0xffffff), "left");

				var cube:Cube = new Cube(materialsList, sliceWidth, 480, 480);
				//cube.x = sliceX - _swfWidth/2 + sliceWidth/2;
				cube.x = sliceX - _cubeWidth/2 + sliceWidth/2;
				cube.z = 240;

				scene.addChild(cube);
				cubes.push(cube);
			}

			startRendering();

			addEventListener(MouseEvent.MOUSE_UP, mouseDownHandler);
		}

		/*
		 * 		CreateBitMap: Converters
		 * 		returns BITMAP from MovieClips
		 *
		 */
		private function createBitMapFromMC(mc:MovieClip):Bitmap
		{
			//Find occupied region
			var region:Rectangle = new Rectangle();
			region = mc.getBounds(this);
			//Build Matrix Transform
			var mat:Matrix = new Matrix(1,0,0,1, 0-region.x, 0-region.y);
			mc.transform.matrix = mat;
			//Draw the bitmap
			var temp:BitmapData = new BitmapData(region.width, region.height, true, 0x00000000);
			temp.draw(mc,mat);
			//Attach the BitmapData to a Bitmap Instance
			var bitmap:Bitmap = new Bitmap(temp);
			//Re apply an Inverse Matrix
			mat = new Matrix(1,0,0,1, region.x, region.y);
			bitmap.transform.matrix = mat;			

			return bitmap;
		}

		/*
		 * 	Create Sliced Bitmap Material from a bitmap
		 * 	@returns:	BitMapMaterial, sliced
		 *
		 *
		 */
		private function createSlicedBitmapMaterial(asset:Bitmap, sliceX:Number, sliceWidth:Number, isFlipped:Boolean = false):BitmapMaterial
		{

			var bitmap:Bitmap = asset;
			var bitmapData:BitmapData = new BitmapData(sliceWidth, 480, false, 0xcc0000);
			//bitmap.pixelSnapping = PixelSnapping.NEVER;

			if(isFlipped)
			{
				var sliceMatrix:Matrix = new Matrix();
				sliceMatrix.translate(-1*sliceWidth, -240);
				sliceMatrix.rotate(Math.PI);
				sliceMatrix.translate(sliceX, 240);
				bitmapData.draw(bitmap, sliceMatrix);
			}
			else
			{
				bitmapData.copyPixels(bitmap.bitmapData, new Rectangle(sliceX, 0, sliceWidth, 480), new Point());
			}
			var material:BitmapMaterial = new BitmapMaterial(bitmapData, true);

			return material;
		}

		/*
		 * 		mouseDownHandler
		 * 		rotates cubes on mouseDown
		 * 		re-skins one side - that has just turned over
		 */
		private function mouseDownHandler(event:MouseEvent):void
		{
			targetRotation += 90 % 360;
			cubes.forEach(cubes_forEachCallback);

			// side to skin
			_sideToSkin = _shownSide[(_shownSidePointer + 3) % 4]; 	// which side is to skin? -> the side which is far out... (predecessing one)
			// slide (XML pointer)
			_slideNum ++;											// xml index -> switch to 1st pic, if max is reached; should be 3 initially! (=> top)
			if (_slideNum > _numSlides-1) _slideNum = 0;			// reset to 0, if limit is reached

			trace('XML slide n: '+_slideNum+ '  SIDE = ' + _shownSide[_shownSidePointer] + ' SKINNING ON: ' + _shownSide[(_shownSidePointer+3)%4]);
			trace('SIDENUM = ' + _shownSidePointer + ' SKINNING ON: ' + (_shownSidePointer+3)%4);

			/*
			 * 	change cube face by re-using the HOLDER class to load new XML data
			 * 	when holder has finished loading, trigger event to create BitMap from MC
			 * 	finally re-skin the selected side
			 */
			switch (_sideToSkin)
			{
				case "back":	{
								_mcBack.setContent(_pictures[_slideNum].@url, _pictures[_slideNum].title, _pictures[_slideNum].description);
								//if (!_mcBack.hasEventListener(Event.COMPLETE))
								_mcBack.addEventListener(Event.COMPLETE, skinBack, false, 0, true);
								break;
								}

				case "bottom":	{
								_mcBottom.setContent(_pictures[_slideNum].@url, _pictures[_slideNum].title, _pictures[_slideNum].description);
								_mcBottom.addEventListener(Event.COMPLETE, skinBottom, false, 0, true);
								break;
								}		

				case "front":	{
								_mcFront.setContent(_pictures[_slideNum].@url, _pictures[_slideNum].title, _pictures[_slideNum].description);
								_mcFront.addEventListener(Event.COMPLETE, skinFront, false, 0, true);
								break;
								}

				case "top":		{
								_mcTop.setContent(_pictures[_slideNum].@url, _pictures[_slideNum].title, _pictures[_slideNum].description);
								_mcTop.addEventListener(Event.COMPLETE, skinTop, false, 0, true);
								break;
								}

			}

			// which side is shown AFTER ROTATION?
			_shownSidePointer ++;
			if (_shownSidePointer > 3) _shownSidePointer = 0;	// max 4 sides

		}

		// skinning functions, after holders are updated
		private function skinBack(e:Event):void
		{
			if (_mcBack.hasEventListener(Event.COMPLETE)) _mcBack.removeEventListener(Event.COMPLETE, skinBack);
			skinCubes(_mcBack, "back");
		}
		private function skinBottom(e:Event):void
		{
			_mcBottom.removeEventListener(Event.COMPLETE, skinBottom);
			skinCubes(_mcBottom, "bottom");
		}
		private function skinFront(e:Event):void
		{
			_mcFront.removeEventListener(Event.COMPLETE, skinFront);
			skinCubes(_mcFront, "front");
		}
		private function skinTop(e:Event):void
		{
			_mcTop.removeEventListener(Event.COMPLETE, skinTop);
			skinCubes(_mcTop, "top");
		}

		private function skinCubes(mc:MovieClip, side:String):void
		{

			trace("RE-SKINNING cube on " + side);

			// re-skin cubes after changing a holder mc
			var material:Bitmap = createBitMapFromMC(mc);
			for (var i:int = 0; i < NUM_SLICES; i++)
			{
				var flipped:Boolean = false;
				// flip only at front / bottom
				if (side == "front" || side == "bottom") flipped = true; else flipped = false;
				var sliceWidth:Number = _cubeWidth / NUM_SLICES;
				var sliceX:Number = sliceWidth * i;
				var sliced_material:BitmapMaterial = createSlicedBitmapMaterial(material, sliceX, sliceWidth, flipped);

				//var matSide = cubes[i].materials.getMaterialByName(side);
				//matSide.functionInMovieMaterial(sliced_material);
				cubes[i].replaceMaterialByName(sliced_material, side);
			}
		}

		/*
		 * 	rotate all cubes after rotation is initiated
		 *
		 *
		 */
		private function cubes_forEachCallback(cube:Cube, index:int, array:Array):void
		{
			index++;
			var time:Number = .3 * index;
			TweenMax.to(cube, time, { rotationX:targetRotation, ease:Quad.easeInOut } );
			//TweenMax.to(cube, time, {x:Math.random()*500-1000, ease:Quad.easeInOut});
		}

		/* LOADERS -> one per side */
		//	BACK -> first function to call --> creates a cascade
		function backLoader(e:Event):void
		{
			//trace("BACK completed in main class: " + e.target);
			_matBack = createBitMapFromMC(_mcBack);
			_mcBack.removeEventListener(Event.COMPLETE, backLoader);
			// load next material
			_mcBottom = new holder(_pictures[1].@url, _pictures[1].title, _pictures[1].description);
			_mcBottom.addEventListener(Event.COMPLETE, bottomLoader, false, 0, true);

		}

		// BOTTOM
		function bottomLoader(e:Event):void
		{
			//trace("BOTTOM completed in main class: " + e.target);
			_matBottom = createBitMapFromMC(_mcBottom);
			_mcBottom.removeEventListener(Event.COMPLETE, bottomLoader);
			// next
			_mcFront = new holder(_pictures[2].@url, _pictures[2].title, _pictures[2].description);
			_mcFront.addEventListener(Event.COMPLETE, frontLoader, false, 0, true);
		}

		function frontLoader(e:Event):void
		{
			//trace("FRONT completed in main class: " + e.target);
			_matFront = createBitMapFromMC(_mcFront);
			_mcFront.removeEventListener(Event.COMPLETE, frontLoader);
			// next
			_mcTop = new holder(_pictures[3].@url, _pictures[3].title, _pictures[3].description);
			_mcTop.addEventListener(Event.COMPLETE, topLoader, false, 0, true);
		}

		function topLoader(e:Event):void
		{
			_matTop = createBitMapFromMC(_mcTop);
			_mcTop.removeEventListener(Event.COMPLETE, topLoader);
			createCubes();
		}

		/*
		 *
		 *		DEPRECATED: for images only
		 *
		 */
		private function createSlicedBitmapMaterialFromAsset(asset:Class, sliceX:Number, sliceWidth:Number, isFlipped:Boolean = false):BitmapMaterial
		{
			var bitmap:Bitmap = new asset() as Bitmap;
			var bitmapData:BitmapData = new BitmapData(sliceWidth, 480, false, 0xcc0000);
			if(isFlipped)
			{
				var sliceMatrix:Matrix = new Matrix();
				sliceMatrix.translate(-180, -240);
				sliceMatrix.rotate(Math.PI);
				sliceMatrix.translate(sliceX, 240);
				bitmapData.draw(bitmap, sliceMatrix);
			}
			else
			{
				bitmapData.copyPixels(bitmap.bitmapData, new Rectangle(sliceX, 0, sliceWidth, 480), new Point());
			}
			var material:BitmapMaterial = new BitmapMaterial(bitmapData, true);

			return material;
		}

		/*
		override protected function onRenderTick(event:Event=null):void {

			  // rotate the scene
			  _camera.yaw(-1);
			  // call the renderer
				super.onRenderTick(event);
		}
		*/

	}
}


Weitere...

Die Toten der Loveparade und die „LehrenR... Verdammte Kinder! Man will "Lehren" ziehen aus dem Tod von 19 Love-Parade Besuchern. Neben den Rücktrittsforderungen gegenüber dem Oberbürgermeister w...
C’mon buddy – all you have to do is pi... Whistleblower - die neuen Journalisten? Die vierte Gewalt wird sie immer genannt: Die Presse. Tatsächlich ist sie nicht Gewalt, doch Macht. Diese T...
Journalismus gefährdet die Demokratie (sic(k)) Wulff apelliert verspätet an die Menschlichkeit in den Medien, bezeichnet den Journalismus um seine Person als Treibjagd. Er hätte gerne auch etwas g...

Dieser Post ist auch verfügbar auf: Englisch