<?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>shiftArray()</title>
	<atom:link href="http://shiftarray.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://shiftarray.com</link>
	<description>Experimenting with Code</description>
	<lastBuildDate>Mon, 26 Mar 2012 00:25:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Still Alive</title>
		<link>http://shiftarray.com/still-alive/</link>
		<comments>http://shiftarray.com/still-alive/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 00:25:23 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=1055</guid>
		<description><![CDATA[Haven&#8217;t posted in a while and I really hate to keep my website out of date. So I&#8217;m just going to quickly go over what my plans are about future updates. First of all I plan to do a complete overhaul of my blog&#8217;s WordPress theme. I&#8217;m going to do it from scratch using HTML5, [...]]]></description>
			<content:encoded><![CDATA[<p>
Haven&#8217;t posted in a while and I really hate to keep my website out of date. So I&#8217;m just going to quickly go over what my plans are about future updates.
</p>
<p>
First of all I plan to do a complete overhaul of my blog&#8217;s WordPress theme. I&#8217;m going to do it from scratch using HTML5, CSS3 and some JavaScript. With that said I am not interested in either HTML5, or CSS3, or JavaScript. I&#8217;m not gonna go into details why I don&#8217;t like either of them, but I&#8217;ll just say I&#8217;ve worked with them long enough and I had my share of frustration. I do have clients who use HTML for their websites and for them I will provide my support. I don&#8217;t think Flash is the answer. I also don&#8217;t think it&#8217;s an alternative to HTML. But with all the hysteria going on around Flash Platform, it still remains one of my favorite platforms to work with.
</p>
<p>
So what&#8217;s next then? For the past few months I&#8217;ve been working with other technologies such as Java (Android), C# and C++. I am extremely fascinated by all of them especially C++. Those are my languages of choice for the future. Like I said I&#8217;m not done with AS3 yet and I will post more code. Only now I have to spend more time doing something other than AS3.
</p>
<p>
I also wish I can make a promise to keep this website up to date, but I can&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/still-alive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving Along 3D Curve</title>
		<link>http://shiftarray.com/moving-along-3d-curve/</link>
		<comments>http://shiftarray.com/moving-along-3d-curve/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 04:09:42 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=1011</guid>
		<description><![CDATA[Movement can look a bit blocky, like it can be seen in this post for instance. One of the ways to create smooth motion is to use Bezier curves. I am aware that there is PathAnimatior class inside Away3D library, but my approach is more general and can be used with almost any 3D library. [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
<p><a href="http://upload.shiftarray.com/flash/away3d/demos/pathmotion.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 required"><img src="http://shiftarray.com/wp-content/uploads/2011/11/path_motion.png" alt="" title="Path Motion" width="600" height="150" class="alignnone size-full wp-image-812" /></a></p>
<p>
Movement can look a bit blocky, like it can be seen in <a href="http://shiftarray.com/as3isolib-astar-pathfinding/">this post</a> for instance. One of the ways to create smooth motion is to use <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">Bezier curves</a>. I am aware that there is <a href="https://github.com/away3d/away3d-core-fp11/blob/master/src/away3d/animators/PathAnimator.as">PathAnimatior</a> class inside Away3D library, but my approach is more general and can be used with almost any 3D library.
</p>
<p><span id="more-1011"></span></p>
<p><strong>PathMovement.as</strong></p>
<p><pre class="brush: js">package shiftarray.demos.away3d 
{
	import away3d.cameras.lenses.PerspectiveLens;
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.View3D;
	import away3d.core.base.Object3D;
	import away3d.debug.AwayStats;
	import away3d.entities.Mesh;
	import away3d.entities.SegmentSet;
	import away3d.materials.ColorMaterial;
	import away3d.primitives.Cone;
	import away3d.primitives.data.Segment;
	import away3d.primitives.LineSegment;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Vector3D;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	public class PathMotion extends View3D 
	{
		
		private var cameraController:HoverDragController;
		// Position zero
		private var origin:Vector3D;
		// Lines container
		private var lines:SegmentSet;
		// Array of generated points
		private var points:Vector.&lt;Vector3D&gt;;
		// Array of generated bezier curves
		private var curves:Vector.&lt;BezierCurve&gt;;
		// Object to follow along the curve
		private var cone:ObjectContainer3D;
		// Used for animation (0 -&gt; 1)
		private var tValue:Number = 0;
		
		public function PathMotion() 
		{
			init();
		}
		
		private function init():void 
		{
			backgroundColor = 0xffffff;
			addChild(new AwayStats(this));
			
			origin = new Vector3D;
			
			generatePoints();
			initLight();
			initCamera();
			init3D();
			
			if (stage) onStage(null);
			else 
				addEventListener(Event.ADDED_TO_STAGE, onStage);
		}
		
		private function generatePoints():void 
		{
			var i:int = 0, 
				l:int = 12, 
				xStep:Number = 100,  
				xOffset:Number = (l &gt;&gt; 1) * xStep * -1;
			points = new &lt;Vector3D&gt;[];
			for (; i &lt; l; i++)
				points[i] = new Vector3D(i * xStep + xOffset, Math.random() * 300 - 150, Math.random() * 200 - 100);
		}
		
		private function initLight():void 
		{
			
		}
		
		private function initCamera():void 
		{	
			camera.lens = new PerspectiveLens();
			camera.z = -500;
			camera.y = 500;
			camera.lookAt(origin);
		}
		
		private function init3D():void 
		{
			// Lines container
			lines = new SegmentSet;
			scene.addChild(lines);
			
			initCurves();
			drawCurve();
			
			// By default cone is Y-Axis oriented
			// To orient cone along Z-Axis, place it inside ObjectContainer3D and apply rotations
			cone = new ObjectContainer3D;
			var inner:Cone = new Cone(new ColorMaterial(0xff6600));
			inner.rotationZ = -90;
			inner.rotationX = 90;
			inner.scale(.25);
			cone.addChild(inner);
			
			scene.addChild(cone);
		}
		
		private function drawCurve():void 
		{
			var i:int = 0, l:int = curves.length;
			var ii:Number, ll:int = 1;
			var c:BezierCurve, p:Vector3D, pp:Vector3D, a:Mesh;
			for (; i &lt; l; ++i) {
				c = curves[i];
				for (ii = 0; ii &lt; ll; ii += .1) {
					p = c.getT(ii);
					if (!pp) pp = p.clone();
					lines.addSegment(new LineSegment(pp, p, 0x333333, 0x333333, 3));
					pp = p.clone();
				}
			}
		}
		
		private function initCurves():void 
		{
			curves = new Vector.&lt;BezierCurve&gt;;
			var p0:Vector3D, p1:Vector3D, p2:Vector3D = points[0].clone();
			var l:int = points.length - 1;
			var i:int = 1;
			var c:int;
			while (i &lt; l) {
				p0 = p2.clone();
				p1 = points[i].clone();
				p2 = points[++i].clone();
				if (i !== l) {
					p2.x = (p1.x + p2.x) / 2;
					p2.y = (p1.y + p2.y) / 2;
					p2.z = (p1.z + p2.z) / 2;
				}
				curves[c++] = new BezierCurve(p0, p1, p2);
			}
		}
		
		public function positionOnCurve(t:Number, path:Vector.&lt;BezierCurve&gt;, object:Object3D, align:Boolean = true):Vector3D
		{
			var i:int, 
				l:int = curves.length,
				curve:BezierCurve;
			
			// Total distance of all curves
			var totalDistance:Number = 0;
			
			// Calclulate total length
			for (; i &lt; l; ++i) {
				curve = curves[i];
				totalDistance += curve.length;
			}
			
			// Distance of t argument
			var tDistance:Number = totalDistance * t;
			
			var ct:Number,
				v:Vector3D,
				c:Number = 0;
			
			// Calculate point
			for (i = 0; i &lt; l; ++i) {
				curve = curves[i];
				if (c + curve.length &gt;= tDistance) {
					c = tDistance - c;
					// t value on curve relative to t of total distance
					ct = c / curve.length;
					// Get point on curve
					v = curve.getT(ct);
					// Position object
					object.position = v;
					// Optionally align object along the curve
					if (align) {
						var q:Vector3D = new Vector3D;
						q.x = curve.p1.x + ct * (curve.p2.x - curve.p1.x);
						q.y = curve.p1.y + ct * (curve.p2.y - curve.p1.y);
						q.z = curve.p1.z + ct * (curve.p2.z - curve.p1.z);
						
						object.lookAt(q);
					}
					
					break;
				}
				
				c += curve.length;
			}
			
			return v;
		}
		
	
		private function onStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onStage);
			stage.addEventListener(Event.RESIZE, resize);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.frameRate = 60;
			
			cameraController = new HoverDragController(camera, stage);
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			resize();
		}
		
		private function onEnterFrame(e:Event):void 
		{
			tValue = tValue &gt; 1 ? 0 : tValue + .001;
			positionOnCurve(tValue, curves, cone, true);
			
			render();
		}
		
		private function resize(e:Event = null):void 
		{
			width = stage.stageWidth;
			height = stage.stageHeight;
		}
		
	}

}
import away3d.cameras.Camera3D;
import away3d.core.base.Object3D;
import away3d.entities.Mesh;
import away3d.materials.ColorMaterial;
import away3d.materials.MaterialBase;
import away3d.primitives.Cube;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Vector3D;

internal class BezierCurve
{
	
	private var _p0:Vector3D;
	private var _p1:Vector3D;
	private var _p2:Vector3D;
	
	public var length:Number;
	
	function BezierCurve(p0:Vector3D, p1:Vector3D, p2:Vector3D)
	{
		this._p0 = p0;
		this._p1 = p1;
		this._p2 = p2;
		
		length = BezierCurve.getBezierLength(this);
	}
	
	// http://segfaultlabs.com/docs/quadratic-bezier-curve-length
	static public function getBezierLength(bezier:BezierCurve):Number
	{
		var a:Vector3D = new Vector3D; 
		var b:Vector3D = new Vector3D;
		var c:Vector3D = new Vector3D;
		
		var p0:Vector3D = bezier.p0;
		var p1:Vector3D = bezier.p1;
		var p2:Vector3D = bezier.p2;
		
		a.x = p0.x - 2 * p1.x + p2.x;
		a.y = p0.y - 2 * p1.y + p2.y;
		a.z = p0.z - 2 * p1.z + p2.z;
		
		b.x = 2 * (p1.x - a.x);
		b.y = 2 * (p1.y - a.y);
		b.z = 2 * (p1.z - a.z);
		
		var A:Number = 4 * (a.x * a.x + a.y * a.y + a.z * a.z);
		
		if (A == 0) return 0;
		
		var B:Number = 4 * (a.x * b.x + a.y * b.y + a.z * b.z);
		var C:Number = b.x * b.x + b.y * b.y + b.z * b.z;
		
		var Sabc:Number = 2 * Math.sqrt(A + B + C);
		var A2:Number = Math.sqrt(A);
		var A32:Number = 2 * A * A2;
		var C2:Number = 2 * Math.sqrt(C);
		var BA:Number = B / A2;
		
		return (A32 * Sabc + A2 * B * (Sabc - C2) + (4 * C * A - B * B) * Math.log(2 * A2 +BA + Sabc) / (BA + C2)) / (4 * A32);
	}
	
	public function toString():String
	{
		return &quot;[&quot; + p0.toString() + &quot;, &quot; + p1.toString() + &quot;, &quot; + p2.toString() + &quot;]&quot;;
	}
	
	public function getT(t:Number):Vector3D
	{
		var v:Vector3D = new Vector3D;
		
		v.x = _p0.x + t * (2 * (1 - t) * (_p1.x - _p0.x) + t * (_p2.x - _p0.x));
		v.y = _p0.y + t * (2 * (1 - t) * (_p1.y - _p0.y) + t * (_p2.y - _p0.y));
		v.z = _p0.z + t * (2 * (1 - t) * (_p1.z - _p0.z) + t * (_p2.z - _p0.z));
		
		return v;
	}
	
	public function get p2():Vector3D 
	{
		return _p2;
	}
	
	public function set p2(value:Vector3D):void 
	{
		_p2 = value;
		length = BezierCurve.getBezierLength(this);
	}
	
	public function get p1():Vector3D 
	{
		return _p1;
	}
	
	public function set p1(value:Vector3D):void 
	{
		_p1 = value;
		length = BezierCurve.getBezierLength(this);
	}
	
	public function get p0():Vector3D 
	{
		return _p0;
	}
	
	public function set p0(value:Vector3D):void 
	{
		_p0 = value;
		length = BezierCurve.getBezierLength(this);
	}
}

internal class Anchor
{
	static private var _mesh:Mesh;
	
	static public function clone():Mesh
	{
		return Mesh(mesh.clone());
	}
	
	static public function get mesh():Mesh 
	{
		if (!_mesh) {
			var material:MaterialBase = new ColorMaterial(0x0066ff);
			_mesh = new Cube(material, 10, 10, 10);
		}
		
		return _mesh;
	}
}

// Class is from away3d-examples-broomstick Github repository
// http://github.com/away3d/away3d-examples-broomstick
internal class HoverDragController
{
	private var _stage : Stage;
	private var _target : Vector3D;
	private var _camera : Camera3D;
	private var _radius : Number = 1000;
	private var _speed : Number = .005;
	private var _dragSmoothing : Number = .1;
	private var _drag : Boolean;
	private var _referenceX : Number = 0;
	private var _referenceY : Number = 0;
	private var _xRad : Number = 0;
	private var _yRad : Number = .5;
	private var _targetXRad : Number = 0;
	private var _targetYRad : Number = .5;
	private var _targetRadius : Number = 1000;

	/**
	 * Creates a HoverDragController object
	 * @param camera The camera to control
	 * @param stage The stage that will be receiving mouse events
	 */
	public function HoverDragController(camera : Camera3D, stage : Stage)
	{
		_stage = stage;
		_target = new Vector3D();
		_camera = camera;

		stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		_stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
		stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
	}

	/**
	 * Amount of &quot;lag&quot; the camera has
	 */
	public function get dragSmoothing() : Number
	{
		return _dragSmoothing;
	}

	public function set dragSmoothing(value : Number) : void
	{
		_dragSmoothing = value;
	}

	/**
	 * The distance of the camera to the target
	 */
	public function get radius() : Number
	{
		return _targetRadius;
	}

	public function set radius(value : Number) : void
	{
		_targetRadius = value;
	}

	/**
	 * The amount by which the camera be moved relative to the mouse movement
	 */
	public function get speed() : Number
	{
		return _speed;
	}

	public function set speed(value : Number) : void
	{
		_speed = value;
	}

	/**
	 * Removes all listeners
	 */
	public function destroy() : void
	{
		_stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		_stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		_stage.removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
		_stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
	}

	/**
	 * The center of attention for the camera
	 */
	public function get target() : Vector3D
	{
		return _target;
	}

	public function set target(value : Vector3D) : void
	{
		_target = value;
	}

	/**
	 * Update cam movement towards its target position
	 */
	private function onEnterFrame(event : Event) : void
	{
		if (_drag) updateRotationTarget();

		_radius = _radius + (_targetRadius - _radius)*dragSmoothing;
		_xRad = _xRad + (_targetXRad - _xRad)*dragSmoothing;
		_yRad = _yRad + (_targetYRad - _yRad)*dragSmoothing;

		// simple spherical position based on spherical coordinates
		var cy : Number = Math.cos(_yRad)*_radius;
		_camera.x = _target.x - Math.sin(_xRad)*cy;
		_camera.y = _target.y - Math.sin(_yRad)*_radius;
		_camera.z = _target.z - Math.cos(_xRad)*cy;
		_camera.lookAt(_target);
	}

	/**
	 * If dragging, update the target position's spherical coordinates
	 */
	private function updateRotationTarget() : void
	{
		var mouseX : Number = _stage.mouseX;
		var mouseY : Number = _stage.mouseY;
		var dx : Number = mouseX - _referenceX;
		var dy : Number = mouseY - _referenceY;
		var bound : Number = Math.PI * .5 - .05;

		_referenceX = mouseX;
		_referenceY = mouseY;
		_targetXRad += dx * _speed;
		_targetYRad += dy * _speed;
		if (_targetYRad &gt; bound) _targetYRad = bound;
		else if (_targetYRad &lt; -bound) _targetYRad = -bound;
	}

	/**
	 * Start dragging
	 */
	private function onMouseDown(event : MouseEvent) : void
	{
		_drag = true;
		_referenceX = _stage.mouseX;
		_referenceY = _stage.mouseY;
	}

	/**
	 * Stop dragging
	 */
	private function onMouseUp(event : MouseEvent) : void
	{
		_drag = false;
	}

	/**
	 * Updates camera distance
	 */
	private function onMouseWheel(event:MouseEvent) : void
	{
		_targetRadius -= event.delta*5;
	}


}
</pre></p>
<p>
I&#8217;ve commented the code to provide some description of the class. Few things to note:</p>
<ul>
<li>By definition Quadratic Bezier curve must have the minimum of 3 points (2 anchors and 1 control point)</li>
<li>In this example curves are generated from points specified in the array</li>
<li>The only points used for anchors are first and last, the rest are control points</li>
<li>Code generates necessary anchor points between specified control points for you</li>
</ul>
<p>The last one is pretty important to understand this demo. Bezier curve takes 3 points, so lets say you specify 4 points (<strong>p0</strong>, <strong>p1</strong>, <strong>p2</strong>, <strong>p3</strong>). So <strong>p0</strong> and <strong>p3</strong> are going to be the first and last anchors respectively. <strong>p1</strong> and <strong>p2</strong> are going to be control points and one more anchor point is going to be generated between <strong>p1</strong> and <strong>p2</strong> (for example <strong>q0</strong>). So the first curve is going to be (<strong>p0</strong>, <strong>p1</strong>, <strong>q0</strong>) and the second curve is going to be (<strong>q0</strong>, <strong>p2</strong>, <strong>p3</strong>). Hope it&#8217;s not too confusing.
</p>
<p>
To wrap it up I want to mention that Bezier curves are pretty easy once you understand them. In the next post I will show you show you can build Bezier curve without fancy formulas just using <a href="http://en.wikipedia.org/wiki/Linear_interpolation">linear interpolation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/moving-along-3d-curve/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ribbons Revisited</title>
		<link>http://shiftarray.com/ribbons-revisited/</link>
		<comments>http://shiftarray.com/ribbons-revisited/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 04:23:43 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=871</guid>
		<description><![CDATA[Decided to revisit my old blog post about ribbons in Away3D. This time using version 4. Note: Using lights will throw runtime error, so no shading yet. Not sure if it&#8217;s my mistake, but I will look into that. Flash Player 11 is required to view the demo. Demo is using eaze-tween for property transitions. [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
<p><a href="http://upload.shiftarray.com/flash/away3d/demos/ribbons4.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 required"><img src="http://shiftarray.com/wp-content/uploads/2011/09/ribbons.png" alt="" title="Away3D 4 Ribbons" width="600" height="150" class="alignnone size-full wp-image-812" /></a></p>
<p>
Decided to revisit <a href="http://shiftarray.com/away3d-ribbons/">my old blog post</a> about ribbons in Away3D. This time using <a href="https://github.com/away3d/away3d-core-fp11">version 4</a>.
</p>
<p>
<strong>Note:</strong> Using lights will throw runtime error, so no shading yet. Not sure if it&#8217;s my mistake, but I will look into that.
</p>
<p>
<a href="http://labs.adobe.com/downloads/flashplayer11.html">Flash Player 11</a> is required to view the demo. Demo is using <a href="http://code.google.com/p/eaze-tween/">eaze-tween</a> for property transitions.
</p>
<p><span id="more-871"></span></p>
<p><strong>Ribbon.as</strong></p>
<p><pre class="brush: js">package shiftarray.away3d.primitives 
{
	import away3d.core.base.data.UV;
	import away3d.core.base.data.Vertex;
	import away3d.core.base.Geometry;
	import away3d.core.base.SubGeometry;
	import away3d.entities.Mesh;
	import away3d.materials.MaterialBase;
	import away3d.tools.FaceHelper;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	
	public class Ribbon extends Mesh 
	{
		private var __geometry:Geometry;
		private var _material:MaterialBase;
		private var width:Number;
		private var numSegments:Number;
		
		private var v0:Vertex, 
					v1:Vertex, 
					v2:Vertex, 
					v3:Vertex;
		
		private var uv0:UV, 
					uv1:UV, 
					uv2:UV, 
					uv3:UV;
		
		private var tx:Number = 0, 
					ty:Number = 0, 
					tz:Number = 0;
		
		/**
		 * 
		 *	@param	material: Ribbon material
		 *	@param	width: Thickness of ribbon
		 *	@param	numSegments: Maximum number of triagles x2 (each segment contains 2 triangles)
		 */
		public function Ribbon(material:MaterialBase, width:Number = 50, numSegments:Number = 150) 
		{
			this._material = material;
			this.width = width;
			this.numSegments = numSegments * 6;
			
			init();
			
			super(_material, __geometry);
		}
		
		private function init():void 
		{
			var subGeometry:SubGeometry = new SubGeometry;
			subGeometry.autoDeriveVertexNormals = true;
			subGeometry.autoDeriveVertexTangents = true;
			subGeometry.updateVertexData(new &lt;Number&gt;[]);
			subGeometry.updateIndexData(new &lt;uint&gt;[]);
			subGeometry.updateUVData(new &lt;Number&gt;[]);
			
			__geometry = new Geometry;
			__geometry.addSubGeometry(subGeometry);
			
			v0 = v2 = new Vertex;
			v1 = v3 = new Vertex;
			v2.x = -width &gt;&gt; 1;
			v3.x = width &gt;&gt; 1;
			
			uv0 = new UV(0, 1);
			uv1 = new UV(1, 1);
			uv2 = new UV(0, 0);
			uv3 = new UV(1, 0);
		}
		
		/**
		 *	Force mesh update 
		 */
		public function update():void
		{
			var il:int = geometry.subGeometries[0].indexData.length;
			if (il &gt; numSegments) {
				FaceHelper.removeFace(this, 0, 0);
				FaceHelper.removeFace(this, 0, 0);
			}
			
			v0 = v2.clone();
			v1 = v3.clone();
			
			v2.x = tx - (width &gt;&gt; 1);
			v2.y = ty;
			v2.z = tz;
			
			v3.x = tx + (width &gt;&gt; 1);
			v3.y = ty;
			v3.z = tz;
			
			FaceHelper.addFace(this, v2, v1, v0, uv2, uv1, uv0, 0);
			FaceHelper.addFace(this, v2, v3, v1, uv2, uv3, uv1, 0);
		}
		
		/**
		 *	Extends existing triangles to specified position
		 *	@param	x
		 *	@param	y
		 *	@param	z
		 */
		public function lineTo(x:Number, y:Number, z:Number):void
		{
			tx = x;
			ty = y;
			tz = z;
			
			update();
		}
		
		override public function get x():Number { return tx; }
		override public function set x(value:Number):void 
		{ 
			tx = value; 
		}
		
		override public function get y():Number { return ty; }
		override public function set y(value:Number):void 
		{ 
			ty = value; 
		}
		
		override public function get z():Number { return tz; }
		override public function set z(value:Number):void 
		{ 
			tz = value; 
		}
		
	}

}</pre></p>
<p><strong>Ribbons.as</strong> (demo)</p>
<p><pre class="brush: js">package shiftarray.demos.away3d 
{
	import away3d.containers.ObjectContainer3D;
	import away3d.debug.AwayStats;
	import away3d.filters.DepthOfFieldFilter3D;
	import away3d.materials.ColorMaterial;
	import aze.motion.eaze;
	import flash.display.StageQuality;
	import flash.events.Event;
	import flash.geom.Vector3D;
	import shiftarray.away3d.containers.BasicView3D;
	import shiftarray.away3d.primitives.Ribbon;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	public class Ribbons extends BasicView3D 
	{
		
		// Limit ribbons movement to specified value for x, y and in 3D space
		private const BOUNDS:Number = 1000;
		private const COLORS:Array = [ 0x00ff44, 0x0099FF, 
									   0xffcc00, 0xff0000, 
									   0xd800ff, 0x00cc00,  
									   0xff6600, 0xff2e00, 
									   0x8000ff, 0x00d4ff];
		
		// Dummy objects used for changing ribbons positions in 3D space
		private var leads:Vector.&lt;Vector3D&gt;;
		private var ribbons:Vector.&lt;Ribbon&gt;;
		
		override protected function init():void
		{
			addChild(new AwayStats(this));
			backgroundColor = 0xf7f7f7;
			super.init();
		}
		
		override protected function initCamera():void
		{
			super.initCamera();
			camera.lens.far = 7000;
		}
		
		override protected function init3D():void
		{
			leads = new Vector.&lt;Vector3D&gt;;
			ribbons = new Vector.&lt;Ribbon&gt;;
			
			var lead:Vector3D; 
			var ribbon:Ribbon;
			var	material:ColorMaterial;
			
			var i:int, l:int = COLORS.length; 
			for (; i &lt; l; ++i) {
				material = new ColorMaterial(COLORS[i], .85);
				material.bothSides = true;
				
				ribbon = new Ribbon(material);
				ribbon.moveTo(randomWithinBounds, randomWithinBounds, randomWithinBounds);
				ribbons.push(ribbon);
				scene.addChild(ribbon);
				
				lead = new Vector3D;
				leads.push(lead);
				
				tween(lead);
			}
		}
		
		private function tween(v:Vector3D):void 
		{
			var t:Number = random(.5, 5);
			eaze(v).to(t, {  x:[[v.x, randomWithinBounds, randomWithinBounds, randomWithinBounds]]
							,y:[[v.y, randomWithinBounds, randomWithinBounds, randomWithinBounds]]
							,z:[[v.z, randomWithinBounds, randomWithinBounds, randomWithinBounds]] } )
				   .onComplete(tween, v);
		}
		
		override protected function onStage(e:Event):void
		{
			super.onStage(null);
			
			stage.quality = StageQuality.LOW;
		}
		
		override protected function onEnterFrame(e:Event):void
		{
			var i:int, l:int = ribbons.length;
			for (; i &lt; l; ++i) {
				
				// Ribbons will line to their associated lead object
				ribbons[i].x += (leads[i].x - ribbons[i].x) / 25;
				ribbons[i].y += (leads[i].y - ribbons[i].y) / 25;
				ribbons[i].z += (leads[i].z - ribbons[i].z) / 25;
				
				ribbons[i].update()
			}
			
			super.onEnterFrame(e);
		}
		
		private function random(min:Number, max:Number):Number
		{
			return min + (max - min) * Math.random();
		}
		
		private function get randomWithinBounds():Number
		{
			return random( -BOUNDS, BOUNDS);
		}
		
	}

}</pre></p>
<p><strong>BasicView3D</strong></p>
<p><pre class="brush: js">package shiftarray.away3d.containers 
{
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.View3D;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Vector3D;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	public class BasicView3D extends View3D 
	{
		
		protected var origin:Vector3D = new Vector3D;
		
		private var autoStart:Boolean;
		
		private var __width:Number;
		private var __height:Number;
		
		public function BasicView3D(width:Number = 0, height:Number = 0, autoStart:Boolean = true) 
		{
			this.autoStart = autoStart;
			this.__width = width;
			this.__height = height;
			
			init();
		}
		
		protected function init():void 
		{
			initLights();
			initCamera();
			init3D();
			
			if (stage) onStage(null);
			else
				addEventListener(Event.ADDED_TO_STAGE, onStage);
		}
		
		protected function initLights():void { }
		
		protected function initCamera():void 
		{
			camera.z = -1000;
			camera.lookAt(origin);
		}
		
		protected function init3D():void { }
		
		protected function onStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onStage);
			stage.addEventListener(Event.RESIZE, resize);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.frameRate = 60;
			
			if (autoStart) startRendering();
			
			resize();
		}
		
		protected function onEnterFrame(e:Event):void 
		{
			singleRender();
		}
		
		protected function resize(e:Event = null):void 
		{
			width = __width == 0 ? stage.stageWidth : __width;
			height = __height == 0 ? stage.stageHeight : __height;
		}
		
		public function singleRender():void
		{
			render();
		}
		
		public function startRendering():void
		{
			addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
		}
		
		public function stopRendering():void
		{
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		public function addObject(object:ObjectContainer3D):ObjectContainer3D
		{
			return scene.addChild(object);
		}
		
	}

}</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/ribbons-revisited/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Away3D with Box2D Physics</title>
		<link>http://shiftarray.com/away3d-with-box2d-physics/</link>
		<comments>http://shiftarray.com/away3d-with-box2d-physics/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 03:08:01 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=873</guid>
		<description><![CDATA[In this demo I&#8217;m combining 3D rendering with 2D physics. Away3D is used for rendering and WCK &#8211; Box2D alchemy port is used for physics. Mouse joints are enabled, so it&#8217;s possible to drag objects around. Flash Player 11 is required to view the demo. package shiftarray.demos.away3d { import away3d.cameras.lenses.PerspectiveLens; import away3d.containers.View3D; import away3d.debug.AwayStats; import [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
<p><a href="http://upload.shiftarray.com/flash/away3d/demos/away3d_wck.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 required"><img src="http://shiftarray.com/wp-content/uploads/2011/09/WCK.png" alt="" title="Away3D WCK" width="600" height="150" class="alignnone size-full wp-image-812" /></a></p>
<p>
In this demo I&#8217;m combining 3D rendering with 2D physics. <a href="https://github.com/away3d/away3d-core-fp11">Away3D</a> is used for rendering and <a href="https://github.com/jesses/wck">WCK</a> &#8211; Box2D alchemy port is used for physics. Mouse joints are enabled, so it&#8217;s possible to drag objects around.
</p>
<p>
<a href="http://labs.adobe.com/downloads/flashplayer11.html">Flash Player 11</a> is required to view the demo.
</p>
<p><span id="more-873"></span><br />
<pre class="brush: js">package shiftarray.demos.away3d 
{
	import away3d.cameras.lenses.PerspectiveLens;
	import away3d.containers.View3D;
	import away3d.debug.AwayStats;
	import away3d.entities.Mesh;
	import away3d.lights.DirectionalLight;
	import away3d.materials.ColorMaterial;
	import away3d.materials.methods.HardShadowMapMethod;
	import away3d.primitives.Cube;
	import away3d.primitives.Plane;
	import away3d.primitives.Sphere;
	import Box2DAS.Common.b2Def;
	import Box2DAS.Common.V2;
	import Box2DAS.Dynamics.b2Body;
	import Box2DAS.Dynamics.b2Fixture;
	import Box2DAS.Dynamics.b2World;
	import Box2DAS.Dynamics.Joints.b2MouseJoint;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	
	public class Physics2D extends View3D 
	{
		
		private const WORLD_SCALE:Number = 30;
		private const RAD2DEG:Number = (180 / Math.PI);
		
		private var world:b2World;
		private var mouseJoint:b2MouseJoint;
		
		private var mouseDown:Boolean = false;
		private var origin:Vector3D;
		private var projectionPoint:Point;
		private var light:DirectionalLight;
		private var sphere:Sphere;
		private var cube:Cube;
		
		public function Physics2D() 
		{
			init();
		}
		
		private function init():void 
		{
			backgroundColor = 0xffffff;
			
			addChild(new AwayStats(this));
			
			origin = new Vector3D;
			projectionPoint = new Point;
			
			initLights();
			initCamera();
			init3D();
			initPhysics();
			
			if (stage) onStage(null);
			else
				addEventListener(Event.ADDED_TO_STAGE, onStage);
				
		}
		
		private function initLights():void 
		{
			light = new DirectionalLight;
			light.direction = new Vector3D(0, -.985, .174)
			scene.addChild(light);
		}
		
		private function initCamera():void 
		{
			camera.lens = new PerspectiveLens(45);
			camera.z = -1500;
			camera.y = 750;
			camera.lookAt(origin);
		}
		
		private function init3D():void 
		{
			var fm:ColorMaterial = new ColorMaterial(0xffffff);
			fm.shadowMethod = new HardShadowMapMethod(light);
			fm.ambient =  .50; 
			fm.specular = .75;
			fm.lights = [light];
			
			var f:Plane = new Plane(fm, 4000, 500, 1, 1, false);
			f.castsShadows = true;
			scene.addChild(f);
			
			var mm:ColorMaterial = new ColorMaterial(0x0099ff);
			mm.shadowMethod = new HardShadowMapMethod(light);
			mm.ambient =  .25; 
			mm.specular = .25;
			mm.lights = [light];
			
			sphere = new Sphere(mm);
			sphere.castsShadows = true;
			
			cube = new Cube(mm);
			cube.castsShadows = true;
		}
		
		private function initPhysics():void 
		{
			world = new b2World(new V2(0.0, -10.0), true);
			b2Def.initialize();
			
			b2Def.polygon.SetAsBox(2000 / WORLD_SCALE, 20 / WORLD_SCALE, new V2(0, -20 / WORLD_SCALE));
			b2Def.polygon.create(world.m_groundBody);
			
			var mesh:Mesh;
			var scale:Number;
			b2Def.body.type = b2Body.b2_dynamicBody;
			for (var i:int; i &lt; 75; i++) {
				
				b2Def.body.position.x = random(-500, 500) / WORLD_SCALE;
				b2Def.body.position.y = random(250, 2750) / WORLD_SCALE;
				
				scale = random(.5, 1);
				
				if (Math.random() &gt; .5) {
					mesh = Mesh(sphere.clone());
					mesh.scale(scale);
					b2Def.body.userData = mesh;
					b2Def.circle.m_radius = scale * 50 / WORLD_SCALE;
					b2Def.fixture.shape = b2Def.circle;
				} else {
					mesh = Mesh(cube.clone());
					mesh.scale(scale);
					b2Def.body.userData = mesh;
					b2Def.polygon.SetAsBox(scale * 50 / WORLD_SCALE, scale * 50 / WORLD_SCALE);
					b2Def.fixture.shape = b2Def.polygon;
				}
				
				b2Def.fixture.density = 1;
				var b:b2Body = b2Def.body.create(world);
				b2Def.fixture.create(b);
				scene.addChild(mesh);
			}
		}
		
		private function updateMouseJoint():void 
		{
			var p:V2 = new V2(projectionPoint.x / WORLD_SCALE, projectionPoint.y / WORLD_SCALE);
			var b:b2Body;
			if (mouseDown &amp;&amp; mouseJoint == null) {
				b = getBodyAtPoint(p);
				if(b) {
					b2Def.mouseJoint.bodyA = world.m_groundBody;
					b2Def.mouseJoint.bodyB = b;
					b2Def.mouseJoint.target.v2 = p;
					b2Def.mouseJoint.collideConnected = true;
					b2Def.mouseJoint.maxForce = 500 * b.GetMass();
					mouseJoint = world.CreateJoint(b2Def.mouseJoint) as b2MouseJoint;
					b.SetAwake(true);
				}
			} else if (!mouseDown &amp;&amp; mouseJoint != null) {
				world.DestroyJoint(mouseJoint);
				mouseJoint = null;
			} else if (mouseJoint) mouseJoint.SetTarget(p);
		}
		
		public function getBodyAtPoint(point:V2):b2Body {
			var body:b2Body = null;
			
			world.QueryPoint(function(f:b2Fixture):Boolean {
				var b:b2Body = f.GetBody();
				if(b.IsDynamic()) {
					body = b;
					return false;
				}
				return true; }, point);
			
			return body;
		}
		
		private function projectMousePosition():void 
		{
			var mv:Vector3D = unproject(stage.mouseX, stage.mouseY);
			var cp:Vector3D = camera.position;
			var dm: Number = mv.z;
			var dc: Number = cp.z;
	
			var d:Number = dm / ( dm - dc );
			
			var v:Vector3D = new Vector3D;
			v.x = mv.x + ( cp.x - mv.x ) * d;
			v.y = mv.y + ( cp.y - mv.y ) * d;
			
			projectionPoint.x = v.x;
			projectionPoint.y = v.y;
			
		}
		
		private function random(min:Number, max:Number):Number
		{
			return min + (max - min) * Math.random();
		}
		
		private function onStageMouseDown(e:MouseEvent):void 
		{
			mouseDown = true;
			stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
		}
		
		private function onStageMouseUp(e:MouseEvent):void 
		{
			mouseDown = false;
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
		}
		
		private function onStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onStage);
			stage.addEventListener(Event.RESIZE, resize);
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.frameRate = 60;
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
			
			resize();
		}
		
		private function onEnterFrame(e:Event):void 
		{
			
			var bb:b2Body = world.GetBodyList();
			while (bb) {
				
				if (bb.GetUserData() is Mesh) {
					var mesh:Mesh = bb.GetUserData() as Mesh;
					mesh.x = bb.GetPosition().x * WORLD_SCALE;
					mesh.y = bb.GetPosition().y * WORLD_SCALE;
					mesh.rotationZ = bb.GetAngle() * RAD2DEG;
					
					if (mesh.y &lt; -1500)
						bb.SetTransform(new V2( random( -250 / WORLD_SCALE, 250 / WORLD_SCALE), 
												random( 500 / WORLD_SCALE, 1500 / WORLD_SCALE)), 
										bb.GetTransform().angle);
				}
				
				bb = bb.GetNext();
			}
			
			
			projectMousePosition();
			updateMouseJoint();
			
			world.Step(1 / 60, 10, 10);
			render();
		}
		
		private function resize(e:Event = null):void 
		{
			width = stage.stageWidth;
			height = stage.stageHeight;
		}
		
	}

}
</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/away3d-with-box2d-physics/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Away3D Directional Particles</title>
		<link>http://shiftarray.com/away3d-directional-particles/</link>
		<comments>http://shiftarray.com/away3d-directional-particles/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 02:08:32 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=925</guid>
		<description><![CDATA[If you played Dirt 3 you know it has a very cool game menu. One of the menu&#8217;s elements is a car driving and drifting around. As it drives around it generates piramid shaped 3d object. In this demo I&#8217;ve tried to recreate Dirt 3&#8242;s game menu using Away3D. It&#8217;s similar to the demo from [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
<p><a href="http://upload.shiftarray.com/flash/away3d/demos/particlesvelocity3d.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 required"><img src="http://shiftarray.com/wp-content/uploads/2011/09/3d_particles_velocity.png" alt="" title="Away3D Directional Particles" width="600" height="150" class="alignnone size-full wp-image-812" /></a></p>
<p>
If you played Dirt 3 you know it has a very cool game menu. One of the menu&#8217;s elements is a car driving and drifting around. As it drives around it generates piramid shaped 3d object. In this demo I&#8217;ve tried to recreate Dirt 3&#8242;s game menu using Away3D. It&#8217;s similar to the demo from <a href="http://shiftarray.com/particles-directional-velocity/" title="Particles Directional Velocity">my previous post</a>.
</p>
<p><span id="more-925"></span></p>
<p><strong>Main.as</strong></p>
<p><pre class="brush: js">package shiftarray.demos.away3d 
{
	import away3d.events.MouseEvent3D;
	import away3d.filters.BlurFilter3D;
	import away3d.lights.DirectionalLight;
	import away3d.materials.ColorMaterial;
	import away3d.materials.methods.HardShadowMapMethod;
	import away3d.primitives.Plane;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Vector3D;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	
	 public class ParticlesVelocity extends BasicSetup 
	{	
		private var emitter:Emitter;
		private var light:DirectionalLight;
		
		override protected function init():void
		{
			super.init();
			
			antiAlias = 0;
			
			filters3d = [new BlurFilter3D(2,2)];
			
		}
		
		override protected function initLights():void
		{
			light = new DirectionalLight;
			light.color = 0xffffff;
			light.specular = .75;
			light.diffuse = 2;
			light.position = new Vector3D(0, 1000, 1000);
			
			var d:Vector3D = light.position.clone();
			d.negate(); d.normalize();
			
			light.direction = d;
			
			scene.addChild(light);
		}
		
		override protected function initCamera():void
		{
			super.initCamera();
			
			camera.y = 1000;
			camera.lookAt(origin);
		}
		
		override protected function init3D():void
		{
			
			var fm:ColorMaterial = new ColorMaterial(0xffffff);
			fm.shadowMethod = new HardShadowMapMethod(light);
			fm.ambient = .5; fm.specular = .75;
			fm.lights = [light];
			
			var f:Plane = new Plane(fm, 4000, 4000, 1, 1, false);
			f.castsShadows = true;
			f.mouseEnabled = true; f.mouseDetails = true;
			f.addEventListener(MouseEvent3D.MOUSE_MOVE, onMouseMove);
			scene.addChild(f);
			
			var pm:ColorMaterial = new ColorMaterial(0x0099ff);
			pm.shadowMethod = new HardShadowMapMethod(light);
			pm.ambient = .5; pm.specular = .75;
			pm.lights = [light];
			
			emitter = new Emitter(scene, pm);
			
		}
		
		private function onMouseMove(e:MouseEvent3D):void 
		{
			emitter.z = e.localZ;
			emitter.x = e.localX;
			emitter.generate();
		}
		
		override protected function onEnterFrame(e:Event):void
		{
			emitter.update();
			super.onEnterFrame(e);
		}
		
	}

}

import away3d.containers.Scene3D;
import away3d.core.base.Geometry;
import away3d.entities.Mesh;
import away3d.materials.MaterialBase;
import away3d.primitives.Cube;

internal class Emitter
{
	
	static private var mesh:Mesh;
	
	public var 	x:Number = 0, _x:Number = 0,
				y:Number = 0, _y:Number = 0,
				z:Number = 0, _z:Number = 0;
	
	private var scene:Scene3D, material:MaterialBase, pls:Vector.&lt;Particle&gt;;
	
	function Emitter(scene:Scene3D, material:MaterialBase)
	{
		this.scene = scene;
		this.material = material;
		
		if (!mesh) mesh = new Cube(material, 25, 25, 25);
		
		pls = new Vector.&lt;Particle&gt;;
	}
	
	private function scalar():Number
	{
		var d:Number = distance();
		return d == 0 ? 0 : 1 / d;
	}
	
	private function distance():Number 
	{
		var dx:Number = x - _x;
		var dz:Number = z - _z;
		return Math.sqrt(dx * dx + dz * dz);
	}
	
	public function update():void
	{
		var i:int, p:Particle;
		for (; i &lt; pls.length; i++) {
			
			p = pls[i];
			
			p.x += p.vx;
			p.y += p.vy;
			p.z += p.vz;
			--p.life;
			
			p.rotationZ -= p.vr;
			
			if (p.life &lt;= 0) {
				scene.removeChild(p);
				pls.splice(i--, 1);
			}
		}
		
		_x = x;
		_y = y;
		_z = z;
	}
	
	public function generate():void
	{
		var p:Particle, s:Number;
		
		p = new Particle(material, mesh.geometry);
		p.castsShadows = true;
		
		p.x = x;
		p.y = y;
		p.z = z;
		
		s = scalar();
		p.vx += (x - _x) * s;
		p.vz += (z - _z) * s;
		p.vr = Math.sqrt(p.vx * p.vx + p.vz * p.vz) * 5;
		
		pls.push(p);
		scene.addChild(p);
		
		
	}
}

internal class Particle extends Mesh
{
	
	public var 	vx:Number, vy:Number, vz:Number, vr:Number,
				life:int;
				
	function Particle(material:MaterialBase, geometry:Geometry)
	{
		
		super(material, geometry);
		
		vx = Math.random() * 2 - 1;
		vy = Math.random();
		vz = Math.random() * 2 - 1;
		
		life = Math.random() * 150;
		
		rotationX = Math.random() * 360;
		rotationY = Math.random() * 360;
		rotationZ = Math.random() * 360;
		
	}
	
	override public function toString():String
	{
		return &quot;[&quot; + x + &quot;, &quot; + y + &quot;, &quot; + z + &quot;]&quot;;
	}
}</pre></p>
<p><strong>BasicSetup.as</strong></p>
<p><pre class="brush: js">package
{
	import away3d.cameras.lenses.PerspectiveLens;
	import away3d.containers.View3D;
	import away3d.debug.AwayStats;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Vector3D;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	
	public class BasicSetup extends View3D 
	{
		protected var origin:Vector3D;
		
		public function BasicSetup() 
		{
			init();
		}
		
		protected function init():void 
		{
			antiAlias = 4;
			backgroundColor = 0xeeeeee;
			addChild(new AwayStats(this));
			
			origin = new Vector3D;
			
			initLights();
			initCamera();
			init3D();
			
			if (stage) onStage(null);
			else
				addEventListener(Event.ADDED_TO_STAGE, onStage);
			
		}
		
		protected function initLights():void { }
		
		protected function initCamera():void 
		{
			camera.lens = new PerspectiveLens(45);
			camera.z = -1000;
			camera.lookAt(origin);
		}
		
		protected function init3D():void 
		{
			
		}
		
		protected function onStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onStage);
			stage.addEventListener(Event.RESIZE, resize);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.frameRate = 60;
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
			
			resize();
		}
		
		protected function onEnterFrame(e:Event):void 
		{
			render();
		}
		
		protected function resize(e:Event = null):void 
		{
			width = stage.stageWidth;
			height = stage.stageHeight;
		}
		
	}

}</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/away3d-directional-particles/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Particles Directional Velocity</title>
		<link>http://shiftarray.com/particles-directional-velocity/</link>
		<comments>http://shiftarray.com/particles-directional-velocity/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 19:57:19 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=907</guid>
		<description><![CDATA[This is a quick demo of how particle adjusts its vector based on emitter&#8217;s position change. The code is very simple. There is an emitter that emits the particles every time its position is changed. Every particle is assigned random velocity vector when it&#8217;s created. Every frame emitter is changing its position based on current [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
<p><a href="http://upload.shiftarray.com/flash/experiments/particles_velocity.swf" rel="shadowbox; width=650; height=500;" title="Particles"><img src="http://shiftarray.com/wp-content/uploads/2011/09/directional_velocity.png" alt="" title="Particles Velocity" width="600" height="150" class="alignnone size-full wp-image-812" /></a></p>
<p>
This is a quick demo of how particle adjusts its vector based on emitter&#8217;s position change. The code is very simple. There is an emitter that emits the particles every time its position is changed. Every particle is assigned random velocity vector when it&#8217;s created. Every frame emitter is changing its position based on current mouse coordinates. Doing so, it generated directional vector which is added to particle&#8217;s existing vector. This creates directional velocity effect.
</p>
<p><span id="more-907"></span><br />
<pre class="brush: js">package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	
	[SWF (width = &quot;650&quot;, height = &quot;500&quot;)]
	public class Main extends Sprite 
	{
		private var canvas:BitmapData;
		private var emitter:Emitter;
		private var bf:BlurFilter;
		private var ct:ColorTransform;
		private var canvasRect:Rectangle;
		private var zeroPoint:Point;
		
		public function Main() 
		{
			init();
		}
		
		private function init():void 
		{
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.frameRate = 60;
			
			canvas = new BitmapData(650, 500, false, 0xff000000);
			canvasRect = canvas.rect;
			addChild(new Bitmap(canvas));
			
			zeroPoint = new Point;
			
			bf = new BlurFilter(4, 4, 1);
			ct = new ColorTransform(1, 1, 1, .95);
			
			emitter = new Emitter;
			
			addEventListener(Event.ENTER_FRAME, onFrame);
		}
		
		private function onFrame(e:Event):void 
		{
			canvas.lock();
			
			emitter.x += (mouseX - emitter.x) * .05;
			emitter.y += (mouseY - emitter.y) * .05;
			
			emitter.update(canvas);
			canvas.applyFilter(canvas, canvasRect, zeroPoint, bf);
			canvas.colorTransform(canvas.rect, ct);
			
			canvas.unlock();
		}
		
	}

}

import flash.display.BitmapData;

internal class Emitter
{
	public var x:Number = 0, _x:Number = 0, 
			   y:Number = 0, _y:Number = 0,
			   color:uint = 0xffffff;
	
	private var pls:Vector.&lt;Particle&gt;;
	
	function Emitter()
	{
		pls = new Vector.&lt;Particle&gt;;
	}
	
	private function scalar():Number
	{
		var d:Number = distance();
		var s:Number = d == 0 ? 0 : 1 / d;
		return s;
	}
	
	private function distance():Number
	{
		var dx:Number = x - _x;
		var dy:Number = y - _y;
		return Math.sqrt(dx * dx + dy * dy);
	}
	
	public function update(canvas:BitmapData):void
	{
		
		var i:int, p:Particle;
		for (; i &lt; pls.length; i++) {
			p = pls[i];
			canvas.setPixel(p.x, p.y, p.color);
			
			p.x += p.vx;
			p.y += p.vy;
			--p.life;
			
			if (p.life &lt;= 0) pls.splice(i--, 1);
		}
		
		if (int(x) - int(_x) != 0 || int(y) - int(_y) != 0) generate();
		
		_x = x;
		_y = y;
		
	}
	
	public function generate():void
	{
		var i:int, l:int = Math.random() * 75, p:Particle, s:Number;
		for (; i &lt; l; i++) {0
			p = new Particle;
			p.x = x;
			p.y = y;
			p.color = color
			
			s = scalar();
			p.vx += (x - _x) * s;
			p.vy += (y - _y) * s;
			
			pls.push(p);
		}
	}
	
}

internal class Particle
{
	
	public var vx:Number = 0, vy:Number = 0, 
				x:Number = 0,  y:Number = 0,
				life:int, color:uint = 0xffffff;
	
	function Particle()
	{
		vx = Math.random() * 2 - 1;
		vy = Math.random() * 2 - 1;
		life = Math.random() * 100;
	}
}</pre></p>
<p>
<strong>Off Topic:</strong> I know Shadowbox post is very popular, so just in case you are wondering, it&#8217;s been moved <a href="http://shiftarray.com/shadowbox-as3-implementation/" title="Shadowbox: AS3 Implementation">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/particles-directional-velocity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Away3D Vertex Transition</title>
		<link>http://shiftarray.com/away3d-vertex-transition/</link>
		<comments>http://shiftarray.com/away3d-vertex-transition/#comments</comments>
		<pubDate>Sat, 21 May 2011 03:54:23 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=837</guid>
		<description><![CDATA[The point of this quick demo is to showcase how you would tween vertices in the latest version of Away3D with a standard tween library, in my case it&#8217;s Eaze Tween. In my previous post I wrote about how vertices are now organized in Vector of numbers rather than objects, so you can&#8217;t just tween [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJava.js"></script>
<p><a href="http://upload.shiftarray.com/flash/away3d/vertextransition/away3dvertextransition.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 required"><img src="http://shiftarray.com/wp-content/uploads/2011/05/away3d_vertex_transition.png" alt="" title="Away3D Vertex Transition" width="600" height="150" class="alignnone size-full wp-image-812" /></a></p>
<p>
The point of this quick demo is to showcase how you would tween vertices in the latest version of Away3D with a standard tween library, in my case it&#8217;s <a href="http://code.google.com/p/eaze-tween/">Eaze Tween</a>. In my <a href="http://shiftarray.com/away3d-perlin-wave/">previous post</a> I wrote about how vertices are now organized in <strong>Vector</strong> of numbers rather than objects, so you can&#8217;t just tween properties of a vertex. To tween properties you would first have to parse them into an object (<a href="http://en.wikipedia.org/wiki/Linked_list">linked list</a> in my example) and then you can transition x, y, z properties in a standard time-start-change-duration way. I would also try to tween the entire array. But to keep track of total time, starting value, change difference and total duration, I would still need an object. So I took an easy way out and used linked list instead. Check out the code.
</p>
<p><span id="more-837"></span></p>
<p>
<strong>VertexTransition.as</strong>
</p>
<p><pre class="brush: java">package shiftarray.demos 
{
	import away3d.cameras.lenses.PerspectiveLens;
	import away3d.containers.View3D;
	import away3d.debug.AwayStats;
	import away3d.events.MouseEvent3D;
	import away3d.lights.DirectionalLight;
	import away3d.materials.BitmapMaterial;
	import away3d.materials.methods.BasicDiffuseMethod;
	import away3d.materials.methods.SoftShadowMapMethod;
	import away3d.primitives.Cube;
	import away3d.primitives.Plane;
	import aze.motion.easing.Cubic;
	import aze.motion.eaze;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.utils.getTimer;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	public class VertexTransition extends View3D 
	{
		
		[Embed(source = '../../../lib/images/texture.png')]
		static private const Texture:Class;
		
		private var light:DirectionalLight;
		private var mesh:Cube;
		private var show:Boolean = true;
		
		private var vertex:Vertex3D;
		private var copy:Vertex3D;
		
		public function VertexTransition() 
		{
			init();
			
			if (stage) onStage(null);
			else
				addEventListener(Event.ADDED_TO_STAGE, onStage);
		}
		
		private function init():void 
		{
			antiAlias = 2;
			
			addChild(new AwayStats(this));
			
			initCamera();
			initLights();
			init3D();
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		private function initCamera():void 
		{
			camera.lens = new PerspectiveLens(45);
			camera.y = 1000;
			
			camera.lookAt(new Vector3D);
		}
		
		private function initLights():void 
		{
			light = new DirectionalLight();
			light.color = 0xffffff;
			light.specular = .75;
			light.diffuse = 2;
			light.position = new Vector3D(0, 1000, 1000);
			
			var d:Vector3D = light.position.clone();
			d.negate(); d.normalize();
			
			light.direction = d;
			
			scene.addChild(light);
		}
		
		private function init3D():void 
		{
			var bd:BitmapData = Bitmap(new Texture).bitmapData;
			
			var meshMaterial:BitmapMaterial = new BitmapMaterial(bd, true, true, true);
			meshMaterial.ambientColor = 0xcccccc;
			meshMaterial.specular = .75;
			meshMaterial.ambient = .5;
			meshMaterial.diffuseMethod = new BasicDiffuseMethod();
			meshMaterial.lights = [light];
			meshMaterial.bothSides = true;
			
			mesh = new Cube(meshMaterial, 400, 400, 400, 10, 10, 10, false);
			mesh.castsShadows = true;
			mesh.y = 250;
			
			var floorMaterial:BitmapMaterial = new BitmapMaterial(checkersTexture(), true, true, true);
			floorMaterial.specular = 1;
			floorMaterial.ambient = 2;
			floorMaterial.ambientColor = 0x333333;
			floorMaterial.diffuseMethod = new BasicDiffuseMethod();
			floorMaterial.shadowMethod = new SoftShadowMapMethod(light, .0006);
			floorMaterial.lights = [light];
			
			var floor:Plane = new Plane(floorMaterial, 2000, 2000, 10, 10, false);
			floor.mouseEnabled = floor.mouseDetails = true;
			floor.addEventListener(MouseEvent3D.CLICK, onFloorClick);
			floor.castsShadows = true;
			
			scene.addChild(mesh);
			scene.addChild(floor);
			
			parseVertexData();
			
		}
		
		private function parseVertexData():void 
		{
			var v:Vertex3D;
			var pv:Vertex3D;
			
			var c:Vertex3D;
			var pc:Vertex3D;
			
			var vd:Vector.&lt;Number&gt; = mesh.geometry.subGeometries[0].vertexData
			var i:int = vd.length - 1;
			
			for (; i &gt; -1; i -= 3) {
				
				v = c = new Vertex3D(vd[i - 2], vd[i - 1], vd[i]);
				v.next = pv;
				pv = v;
				
				c = new Vertex3D(vd[i - 2], vd[i - 1], vd[i]);
				c.next = pc;
				pc = c;
				
				
			}
			
			vertex = v;
			copy = c;
		}
		
		private function onFloorClick(e:MouseEvent3D):void 
		{
			
			var lx:Number = e.localX - mesh.x;
			var ly:Number = e.localY - mesh.y;
			var lz:Number = e.localZ - mesh.z;
			
			show = !show;
			
			var v:Vertex3D;
			var c:Vertex3D;
			var d:Number;
			var p:Object;
			
			var indexed:Vector.&lt;Object&gt; = new &lt;Object&gt;[];
			
			v = vertex;
			c = copy;
			
			while(v) {
				
				eaze(v).killTweens();
				
				if (show) {
					v.x = lx;
					v.y = ly;
					v.z = lz;
				}
				
				var a:Number = v.x - (show ? c.x : lx);
				var b:Number = v.y - (show ? c.y : ly);
				var f:Number = v.z - (show ? c.z : lz);
				
				d = Math.sqrt(a * a + b * b + f * f);
				
				p = {};
				p.x = show ? c.x : lx;
				p.y = show ? c.y : ly;
				p.z = show ? c.z : lz;
				
				indexed.push( { distance:d, vertex:v, newState:p } );
				
				v = v.next;
				c = c.next;
				
			}
			
			indexed.sort(sortOnDistance);
			
			var i:int = 0;
			var l:int = indexed.length;
			var obj:Object;
			for (; i &lt; l; i++) {
				
				var delay:Number = show ? ((l - 1 - i) * .001) : (i * .001);
				obj = indexed[i];
				v = obj.vertex;
				
				eaze(v) .delay 	(delay)
						.to    	(.75, obj.newState)
						.easing (show ? Cubic.easeOut : Cubic.easeIn);
										
			}
			
		}
		
		private function sortOnDistance(a:Object, b:Object):int
		{
			if  (a.distance &gt; b.distance) return 1;
			else if 
				(a.distance &lt; b.distance) return -1;
			else 
				return 0
		}
		
		private var vertexData:Vector.&lt;Number&gt;;
		private function updateVerticies():void 
		{
			vertexData = new &lt;Number&gt;[];
			var v:Vertex3D = vertex;
			while (v) {
				vertexData.push(v.x, v.y, v.z);
				v = v.next;
			}
			
			mesh.geometry.subGeometries[0].updateVertexData(vertexData)
		}
		
		private function checkersTexture():BitmapData
		{
			var bd:BitmapData = new BitmapData(512, 512, false, 0xff000000);
			
			for (var i:int = 0; i &lt; 8 * 8; i++) {
				bd.fillRect(new Rectangle((i % 8) * 64, int(i / 8) * 64, 64 * .5, 64 * .5), 0xeeeeee);
				bd.fillRect(new Rectangle((i % 8) * 64 + 64/2, int(i / 8) * 64 + 64/ 2, 64 * .5, 64 * .5), 0xffffff);
			}
			
			return bd;
		}
		
		private var origin:Vector3D = new Vector3D;
		private function onEnterFrame(e:Event):void 
		{
			
			camera.x = Math.sin(getTimer() / 3000) * 1500;
			camera.z = Math.cos(getTimer() / 3000) * 1500;
			
			camera.lookAt(origin);
			
			updateVerticies();
			render();
		}
		
		private function onStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onStage);
			stage.addEventListener(Event.RESIZE, resize);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.frameRate = 60;
			
			resize();
		}
		
		private function resize(e:Event = null):void 
		{
			width = stage.stageWidth;
			height = stage.stageHeight;
		}
		
	}

}

internal class Vertex3D
{
	public var next:Vertex3D;
	
	public var x:Number;
	public var y:Number;
	public var z:Number;
	
	public function Vertex3D(x:Number = 0, y:Number = 0, z:Number = 0)
	{
		this.x = x;
		this.y = y;
		this.z = z;
	}
	
	public function toString():String
	{
		return &quot;[&quot; + x.toString() + &quot;, &quot; + y.toString() + &quot;, &quot; + z.toString() + &quot;]&quot;;
	}
}
</pre></p>
<p>
Image used for texture is copyright of <a href="http://www.hdwallpapers.net/">hdwallpapers.net</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/away3d-vertex-transition/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Away3D Perlin Wave</title>
		<link>http://shiftarray.com/away3d-perlin-wave/</link>
		<comments>http://shiftarray.com/away3d-perlin-wave/#comments</comments>
		<pubDate>Mon, 16 May 2011 05:50:06 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Source]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=811</guid>
		<description><![CDATA[Updated 2011-06-07 Added code comments. Most of the code looks green now, because syntax highlighter doesn&#8217;t pick up comment blocks very well. Copy and paste the code into your editor to make it more readable. Continuing working with a brilliant new Away3D 4 API, I&#8217;ve made a quick demo that demonstrates vertex manipulation. Basically mesh [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJava.js"></script>
<p><a href="http://upload.shiftarray.com/flash/away3d/perlinwave/away3dperlinwave.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 required"><img src="http://shiftarray.com/wp-content/uploads/2011/05/a3dperlinwave.png" alt="" title="Away3D Perlin Wave" width="600" height="150" class="alignnone size-full wp-image-812" /></a></p>
<p>
<i><b>Updated 2011-06-07</b> Added code comments. Most of the code looks green now, because syntax highlighter doesn&#8217;t pick up comment blocks very well. Copy and paste the code into your editor to make it more readable.</i>
</p>
<p>
Continuing working with a brilliant new Away3D 4 API, I&#8217;ve made a quick <a href="http://archive.shiftarray.com/Flash/away3d/perlinwave/away3dperlinwave.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 (Incubator) required">demo</a> that demonstrates vertex manipulation. Basically mesh <strong>geometry</strong> property (<strong>Geometry</strong> class) now doesn&#8217;t have an array of objects representing vertex. It rather has <strong>Vector</strong> of type <strong>SubGeometry</strong> through <strong>subGeometries</strong> property which has <strong>vertexData</strong> property which is a <strong>Vector</strong> of type <strong>Number</strong> which contains mesh&#8217;s vertex information. It makes vertex data access much faster, but it make manipulating vertices a bit more complicated as well, since now you can&#8217;t just change vertex object property, you have to update vertex data with <strong>Vector</strong> of type <strong>Number</strong> containing all mesh&#8217;s vertex information using <strong>updateVertexData</strong> method inside <strong>SubGeometry</strong> class.
</p>
<p><span id="more-811"></span></p>
<p>
In some cases this kind of arrangement can be fast and efficient, like in <a href="http://archive.shiftarray.com/Flash/away3d/perlinwave/away3dperlinwave.swf" rel="shadowbox; width=1100; height=700;" title="Flash Player 11 (Incubator) required">this demo</a>. But in some cases it can complicate things, as you will be able to see in my next post. Still, event though it&#8217;s different from previous Away3D version 3, accessing vertex data in the new API seems fast and efficient.
</p>
<p>
<strong>PerlinWave.as</as>
</p>
<p><pre class="brush: java">package shiftarray.demos 
{
	import away3d.containers.View3D;
	import away3d.lights.PointLight;
	import away3d.materials.ColorMaterial;
	import away3d.primitives.Plane;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.system.System;
	
	/**
	 * ...
	 * @author Alex Logashov
	 */
	public class PerlinWave extends View3D 
	{
		
		private var bitmapData:BitmapData;
		private var scrollPoint:Point;
		private var seed:Number;
		private var plane:Plane;
		
		public function PerlinWave() 
		{
			if (stage) init(null);
			else
				addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function random(min:Number, max:Number):Number
		{
			return Math.random() * (max - min) + min;
		}
		
		private function init3D():void 
		{
			antiAlias = 4;
			
			var light:PointLight = new PointLight();
			light.position = new Vector3D(0, 1000, 0);
			light.radius = 500;
            light.fallOff = 4000;
			light.specular = .35;
			light.diffuse = 1;
			scene.addChild(light);
			
			var material:ColorMaterial = new ColorMaterial(0x0066cc);
			material.specular = .25;
			material.ambient = .35;
			material.ambientColor = 0x333333;
			material.lights = [light];
			
			plane = new Plane(material, 3000, 3000, 50, 50, false);
			
			scene.addChild(plane);
			
			camera.position = new Vector3D(0, 1000, 3000);
			camera.lens.near = .1;
			camera.lens.far = 15000;
			camera.lookAt(new Vector3D());
			
		}
		
		private function init(e:Event):void 
		{	
			removeEventListener(Event.ADDED_TO_STAGE, init);
			stage.addEventListener(Event.RESIZE, resize, false, 0, true);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.frameRate = 60;
			
			scrollPoint = new Point(0, 0);
			
			seed = random(250, 500);
			/*
				Even though our plane is only 50x50 segments it has 51 columns and rows of vertices. Hence 51x51 px BitmapData.
				For example a 2x2 segment plane would have the following map of vertices position:
						
						0 	1 	2
						
						3 	4 	5
						
						6 	7 	8
				
			 */ 
			bitmapData = new BitmapData(51, 51, false, 0xff333333);
			addChild(new Bitmap(bitmapData));
			
			init3D();
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			resize();
			
		}
		
		private function resize(e:Event = null):void 
		{
			width = stage.stageWidth;
			height = stage.stageHeight;
		}
		
		private function onEnterFrame(e:Event):void 
		{
			scrollPoint.y += 1;
			bitmapData.perlinNoise(50, 50, 1, seed, true, true, 7, true, [scrollPoint]);
			
			// Get current vertex data from mesh's geometry
			var v:Vector.&lt;Number&gt; = plane.geometry.subGeometries[0].vertexData;
			/*
				Vertex is stored in array of numbers. Each representing x, y, z, x, y, z and so on.
				We need y because that's what we will be displacing.
				So we start with index of 1 and keep incrementing by 3 skipping over z and x values.
			*/
			var i:int = 1;
			var l:int = v.length;
			// Counter integer to get row and coulumn of a pixel inside BitmapData.
			var c:int;
			var px:uint;
			for (; i &lt; l; i += 3, c++) {
				
				// Get pixel at x and y position
				px = bitmapData.getPixel(c % 51, int(c / 51));
				/*
					Displace y position by the range from -450 to 450.
					White color is going to be the highest value, black the lowest.
				*/ 
				v[i] = 900 * px / 0xffffff - 450;
			}
			
			// Finally update vertex data with our modified vector of numbers.
			plane.geometry.subGeometries[0].updateVertexData(v);
			
			render();
			
		}
		
	}

}</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/away3d-perlin-wave/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Away3D Twitter Search</title>
		<link>http://shiftarray.com/away3d-twitter-search/</link>
		<comments>http://shiftarray.com/away3d-twitter-search/#comments</comments>
		<pubDate>Sun, 08 May 2011 07:00:31 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://shiftarray.com/?p=778</guid>
		<description><![CDATA[Finally got the time to work with the latest Away3D version. To try it out I&#8217;ve made a simple Flash app that uses Twitter API to search tweets. It uses Away3D 4 for 3D rendering, JiglibFlash Away Physics for physics, Eaze Tween for tweening, MinimalComps for UI controls. One thing to note is demo can [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJava.js"></script>
<p><a href="http://upload.shiftarray.com/flash/away3d/away3dtwitter/Away3DTwitter.swf" rel="shadowbox; width=1024; height=700;" title="Flash Player 11 required"><img src="http://shiftarray.com/wp-content/uploads/2011/05/away3dtwitter.png" alt="" title="Away3D Twitter" width="600" height="150" class="alignnone size-full wp-image-784" /></a></p>
<p>
Finally got the time to work with the latest <a href="http://away3d.com">Away3D</a> version. To try it out I&#8217;ve made a simple Flash app that uses Twitter API to search tweets. It uses Away3D 4 for 3D rendering, <a href="http://www.jiglibflash.com/blog/"><del datetime="2011-09-09T02:42:56+00:00">JiglibFlash</del></a> <a href="https://github.com/away3d/awayphysics-core-fp11">Away Physics</a> for physics, <a href="http://code.google.com/p/eaze-tween/">Eaze Tween</a> for tweening, <a href="http://code.google.com/p/minimalcomps/">MinimalComps</a> for UI controls.
</p>
<p>
One thing to note is demo can be a bit slow. This is entirely due to physics, not the rendering. JiglibFlash uses AS3 for its calculations. With lots of objects it can slow things down noticeably. Hopefully it will be faster in the future. Still it&#8217;s a great library with very simple API. Away3D 4 API is quite simple as well and makes working with HW accelerated graphics in FP 11 very easy. Even though version 4 has got a lot of very nice features to play with, it does feel a bit limited compared to version 3. But version 4 is still in alpha stage so more features will probably come later. Still it is very stable and easy to get started with.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/away3d-twitter-search/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rebranding&#8230;</title>
		<link>http://shiftarray.com/rebranding/</link>
		<comments>http://shiftarray.com/rebranding/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 01:46:45 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://inside.silverbase.net/?p=724</guid>
		<description><![CDATA[Updated 2011-04-15 silverbase.net is now shiftarray.com. Going to silverbase.net will redirect to shiftarray.com I think it&#8217;s about time for me to write a new blog post. I know I haven&#8217;t been active very much lately, mainly for being lazy. I mean, I can come up with excuses such as &#8211; &#8220;I was busy at work&#8221; [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJScript.js"></script>
            <script type="text/javascript" src="http://shiftarray.com/wp-content/plugins/wordpress-code-snippet/scripts/shBrushJava.js"></script>
<p>
<i><b>Updated 2011-04-15</b> silverbase.net is now shiftarray.com. Going to silverbase.net will redirect to shiftarray.com</i>
</p>
<p>
I think it&#8217;s about time for me to write a new blog post. I know I haven&#8217;t been active very much lately, mainly for being lazy. I mean, I can come up with excuses such as &#8211; &#8220;I was busy at work&#8221; or &#8220;Playing too many video games&#8221;, but that&#8217;s just it &#8211; excuses.
</p>
<p>
So what&#8217;s up!? Really &#8211; not much. But I was digging a lot lately into Molehill API, Away3D 4 and Flash drawing API. It&#8217;s just good stuff. So expect more code soon.
</p>
<p>
Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftarray.com/rebranding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

