Source: depthjs_1.1.3.js

/*
DepthJS version 1.1.3

Copyright (c) 2015 MBMedia.cc | for info go to http://mbmedia.cc/depthjs/

Licensed under MIT license

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

window.depthjs = window.depthjs || {};

/**
Quaternion is an internally used class. A Quaternion instance is attached to a {@link DisplayObject3D} object's transform3D property (which is itself an instance of the {@link Transform3D} class). It is part of internal calculations, and should only be accessed by extremely advanced users. You should not have to deal with this class in normal usage of the engine.
@class Quaternion
@arg {Number} [w=0] - New instance's w value.
@arg {Number} [x=0] - New instance's x value.
@arg {Number} [y=0] - New instance's y value.
@arg {Number} [z=0] - New instance's z value.
**/
depthjs.Quaternion = function(aw, ax, ay, az)
{
	"use strict";
	
	/**
	The Quaternion instance's w property. Used for calculations.
	@var Quaternion#w {Number}
	@public
	@default 0
	**/
	/**
	The Quaternion instance's x property. Used for calculations.
	@var Quaternion#x {Number}
	@public
	@default 0
	**/
	/**
	The Quaternion instance's y property. Used for calculations.
	@var Quaternion#y {Number}
	@public
	@default 0
	**/
	/**
	The Quaternion instance's z property. Used for calculations.
	@var Quaternion#z {Number}
	@public
	@default 0
	**/
	this.w = typeof aw !== 'undefined' ? aw : 0;
	this.x = typeof ax !== 'undefined' ? ax : 0;
	this.y = typeof ay !== 'undefined' ? ay : 0;
	this.z = typeof az !== 'undefined' ? az : 0;
	
	/**
	This method concatenates the values of another Quaternion with this Quaternion and then sets the resulting values to this Quaternion's w, z, y, and z properties. This is vital for forward kinematics of 3D rotations. There is no return; the Quaternion intance on which this method is called (as opposed to the one supplied as a parameter) is modified as a result.
	@method Quaternion#concatenate
	@public
	@arg {Quaternion} q - Quaternion to concatenate with this one.
	**/
	this.concatenate = function(q)
	{
		var w1 = q.w;
		var x1 = q.x;
		var y1 = q.y;
		var z1 = q.z;
		
		var _w = w1 * this.w - x1 * this.x - y1 * this.y - z1 * this.z;
		var _x = w1 * this.x + x1 * this.w + y1 * this.z - z1 * this.y;
		var _y = w1 * this.y - x1 * this.z + y1 * this.w + z1 * this.x;
		var _z = w1 * this.z + x1 * this.y - y1 * this.x + z1 * this.w;
		
		this.w = _w;
		this.x = _x;
		this.y = _y;
		this.z = _z;
	}
	
	/**
	A method for getting a {@link EulerAngle} based on the current Quaternion.
	@method Quaternion#toEuler
	@public
	@returns {EulerAngle} Returns a new EulerAngle instance.
	**/
	this.toEuler = function()
	{
		var w2 = this.w * this.w;
		var x2 = this.x * this.x;
		var y2 = this.y * this.y;
		var z2 = this.z * this.z;
		
		var phi, theta, psi;
		
		var tester = this.w * this.y - this.z * this.x;
		
		if (tester > 0.499999)
		{
			phi   = -2 * atan2(this.w, this.x);
			theta = Math.PI / 2;
			psi   = Math.PI;
			
			return new depthjs.EulerAngle(phi, theta, psi);
		}
		else if (tester < -0.499999)
		{
			phi   = -2 * atan2(this.w, this.x);
			theta = -Math.PI / 2;
			psi   = Math.PI;
			
			return new depthjs.EulerAngle(phi, theta, psi);
		}
		
		phi   = atan2(  2 * (this.w * this.x + this.y * this.z) , 1 - 2 * (x2 + y2) );
		theta = asin (  2 *  tester                                                 );
		psi   = atan2(  2 * (this.w * this.z + this.x * this.y) , 1 - 2 * (y2 + z2) );
		
		return new depthjs.EulerAngle(phi, theta, psi);
	}
	
	/**
	A method for updating the w, x, y, and z properties based on a {@link EulerAngle} intance.
	@method Quaternion#updateFromEuler
	@public
	@arg {EulerAngle} euler - EulerAngle instance to update from.
	**/
	this.updateFromEuler = function(euler)
	{
		var hPhi   = euler.phi   / 2;
		var hTheta = euler.theta / 2;
		var hPsi   = euler.psi   / 2;
		
		var sin_hPhi   = sin(  hPhi), cos_hPhi   = cos(  hPhi);
		var sin_hTheta = sin(hTheta), cos_hTheta = cos(hTheta);
		var sin_hPsi   = sin(  hPsi), cos_hPsi   = cos(  hPsi);
		
		this.w = cos_hPhi * cos_hTheta * cos_hPsi + sin_hPhi * sin_hTheta * sin_hPsi;
		this.x = sin_hPhi * cos_hTheta * cos_hPsi - cos_hPhi * sin_hTheta * sin_hPsi;
		this.y = cos_hPhi * sin_hTheta * cos_hPsi + sin_hPhi * cos_hTheta * sin_hPsi;
		this.z = cos_hPhi * cos_hTheta * sin_hPsi - sin_hPhi * sin_hTheta * cos_hPsi;
	}
	
	/**
	Normalizes the Quaternion.
	@method Quaternion#normalize
	@public
	**/
	this.normalize = function()
	{
		var magnitude = sqrt( this.w * this.w + this.x * this.x + this.y * this.y + this.z * this.z );
		this.w /= magnitude; this.x /= magnitude; this.y /= magnitude; this.z /= magnitude;
	}
	
	/**
	Produces a new Quaternion instance that is duplicate of the current one.
	@method Quaternion#clone
	@public
	@returns {Quaternion} Returns a new Quaternion instance.
	**/
	this.clone = function()
	{
		return new depthjs.Quaternion(this.w, this.x, this.y, this.z);
	}
	
	/**
	A shortcut to copy the w, x, y, and z values of another Quaternion to this one.
	@method Quaternion#copy
	@public
	@arg {Quaternion} q - The Quaternion instance to copy values from.
	**/
	this.copy = function(q)
	{
		this.w = q.w; this.x = q.x; this.y = q.y; this.z = q.z;
	}
	
	/**
	A shortcut to copy the inverted result of another Quaternion to this one.
	@method Quaternion#copyInverse
	@public
	@arg {Quaternion} p - The Quaternion instance to invert and then get values from.
	**/
	this.copyInverse = function(q)
	{
		var qw = q.w, qx = q.x, qy = q.y, qz = q.z;
		var d = qw*qw + qx*qx + qy*qy + qz*qz;
		this.w =  qw/d;
		this.x = -qx/d;
		this.y = -qy/d;
		this.z = -qz/d;
	}
	
	/**
	Returns a String representation of the Quaternion instance's values.
	@method Quaternion#toString
	@public
	@returns {String} Returns a string with an object notation form of the w, x, y, and z properties.
	**/
	this.toString = function()
	{
		return "{w:"+this.w+", x:"+this.x+", y:"+this.y+", z:"+this.z+"}";
	}
	
	// hiking over math stuff for ease of writing...
	var asin = Math.asin;
	var sqrt = Math.sqrt;
	var atan2 = Math.atan2;
	var cos = Math.cos;
	var sin = Math.sin;
}

/**
Multiplies two Quaterions together. Note: multiplication of quaternions is non-commutative. Order matters.
@method Quaternion.multiply
@public
@arg {Quaternion} q1 - The first quaternion to multiply.
@arg {Quaternion} q2 - The second quaternion to multiply.
@returns {Quaternion} Returns a new Quaternion with the result of the multiplication.
**/
depthjs.Quaternion.multiply = function(q1, q2)
{
	"use strict";
	
	var w1 = q1.w, w2 = q2.w;
	var x1 = q1.x, x2 = q2.x;
	var y1 = q1.y, y2 = q2.y;
	var z1 = q1.z, z2 = q2.z;
	
	var _w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2;
	var _x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2;
	var _y = w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2;
	var _z = w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2;
	
	return new depthjs.Quaternion(_w, _x, _y, _z);
}

///////////////////////////////////////////////////////////////////////////////////////////////

/**
Point3D is an internally used class. A Point3D instance is attached to a {@link DisplayObject3D} object's transform3D property (which is itself an instance of the {@link Transform3D} class). It is part of internal calculations, and should only be accessed by advanced users. You should not have to deal with this class in normal usage of the engine.
@class Point3D
@arg {Number} [x=0] - New instance's x coordinate value.
@arg {Number} [y=0] - New instance's y coordinate value.
@arg {Number} [z=0] - New instance's z coordinate value.
**/
depthjs.Point3D = function(aX, aY, aZ)
{
	"use strict";
	
	/**
	The Point3D instance's x property. Used for calculations.
	@var Point3D#x {Number}
	@public
	@default 0
	**/
	/**
	The Point3D instance's y property. Used for calculations.
	@var Point3D#y {Number}
	@public
	@default 0
	**/
	/**
	The Point3D instance's z property. Used for calculations.
	@var Point3D#z {Number}
	@public
	@default 0
	**/
	this.x = typeof aX !== 'undefined' ? aX : 0;
	this.y = typeof aY !== 'undefined' ? aY : 0;
	this.z = typeof aZ !== 'undefined' ? aZ : 0;
	
	/**
	This method will rotate a supplied Point3D's coordinate values around origin 0,0,0 based on the supplied {@link EulerAngle} object's rotation. It will then set this Point3D's coordinate values to the result.
	@method Point3D#rotateAndUpdate
	@public
	@arg {Point3D} point - Point3D values to rotate.
	@arg {EulerAngle} angle - EulerAngle rotational values to rotate by.
	**/
	this.rotateAndUpdate = function(point, angle)
	{
		var phi   = angle.phi;
		var theta = angle.theta;
		var psi   = angle.psi;
		
		var srz = sin(phi),   crz = cos(phi);
		var sry = sin(theta), cry = cos(theta);
		var srx = sin(psi),   crx = cos(psi);
		
		var _X = point.x;
		var _Y = point.y;
		var _Z = point.z;
			
		var xy, xz, yx, yz, zx, zy;
			
		xy = (crx * _Y) - (srx * _Z);
		xz = (srx * _Y) + (crx * _Z);
		yz = (cry * xz) - (sry * _X);
		yx = (sry * xz) + (cry * _X);
		zx = (crz * yx) - (srz * xy);
		zy = (srz * yx) + (crz * xy);
		
		this.x += zx;
		this.y += zy;
		this.z += yz;
	}
	
	/**
	A shortcut method for setting the x, y, and z properties.
	@method Point3D#updateData
	@public
	@arg {Number} x - New x value.
	@arg {Number} y - New y value.
	@arg {Number} z - New z value.
	**/
	this.updateData = function(_X, _Y, _Z)
	{
		this.x = _X;
		this.y = _Y;
		this.z = _Z;
	}
	
	/**
	Produces a new Point3D instance that is duplicate of the current one.
	@method Point3D#clone
	@public
	@returns {Point3D} Returns a new Point3D instance.
	**/
	this.clone = function()
	{
		return new depthjs.Point3D(this.x, this.y, this.z);
	}
	
	/**
	A shortcut to copy the x, y, and z values of another Point3D to this one.
	@method Point3D#copy
	@public
	@arg {Point3D} p - The Point3D instance to copy values from.
	**/
	this.copy = function(p)
	{
		this.x = p.x;
		this.y = p.y;
		this.z = p.z;
	}
	
	/**
	A shortcut to copy the inverted (negative) x, y, and z values of another Point3D to this one.
	@method Point3D#copyInverse
	@public
	@arg {Point3D} p - The Point3D instance to copy inverted values from.
	**/
	this.copyInverse = function(p)
	{
		this.x = -p.x;
		this.y = -p.y;
		this.z = -p.z;
	}
	
	/**
	Returns a String representation of the Point3D instance's values.
	@method Point3D#toString
	@public
	@returns {String} Returns a string with an object notation form of the x, y, and z properties.
	**/
	this.toString = function()
	{
		return "{X:"+this.x+", Y:"+this.y+", Z:"+this.z+"}";
	}
	
	// hiking over math stuff for ease of writing...
	var cos = Math.cos;
	var sin = Math.sin;
}

/**
A static verion of the non-static [rotateAndUpdate]{@link Point3D#rotateAndUpdate} method which returns a new Point3D with the modified valies.
@method Point3D.rotate
@public
@arg {Point3D} point - Point3D values to rotate.
@arg {EulerAngle} angle - EulerAngle rotational values to rotate by.
@returns {Point3D} Returns a new Point3D with the end result applied.
**/
depthjs.Point3D.rotate = function(point, angle)
{
	"use strict";
	
	var phi   = angle.phi;
	var theta = angle.theta;
	var psi   = angle.psi;
	
	var srz = sin(phi),   crz = cos(phi);
	var sry = sin(theta), cry = cos(theta);
	var srx = sin(psi),   crx = cos(psi);
	
	var _X = point.x;
	var _Y = point.y;
	var _Z = point.z;
		
	var xy, xz, yx, yz, zx, zy;
		
	xy = (crx * _Y) - (srx * _Z);
	xz = (srx * _Y) + (crx * _Z);
	yz = (cry * xz) - (sry * _X);
	yx = (sry * xz) + (cry * _X);
	zx = (crz * yx) - (srz * xy);
	zy = (srz * yx) + (crz * xy);
	
	return new depthjs.Point3D(zx, zy, yz);
}

/////////////////////////////////////////////////////////////////////////////////////

/**
EulerAngle is an internally used class. A EulerAngle instance is attached to a {@link DisplayObject3D} object's transform3D property (which is itself an instance of the {@link Transform3D} class). It is part of internal calculations, and should only be accessed by extremely advanced users. You should not have to deal with this class in normal usage of the engine.
@class EulerAngle
@arg {Number} [phi=0] - New instance's phi value.
@arg {Number} [theta=0] - New instance's theta value.
@arg {Number} [psi=0] - New instance's psi value.
**/
depthjs.EulerAngle = function(aphi, atheta, apsi)
{
	"use strict";
	
	/**
	The EulerAngle instance's phi property. Used for calculations.
	@var EulerAngle#phi {Number}
	@public
	@default 0
	**/
	/**
	The EulerAngle instance's theta property. Used for calculations.
	@var EulerAngle#theta {Number}
	@public
	@default 0
	**/
	/**
	The EulerAngle instance's psi property. Used for calculations.
	@var EulerAngle#psi {Number}
	@public
	@default 0
	**/
	this.phi   = typeof aphi   !== 'undefined' ? aphi   : 0;
	this.theta = typeof atheta !== 'undefined' ? atheta : 0;
	this.psi   = typeof apsi   !== 'undefined' ? apsi   : 0;
	
	/**
	A shortcut method for setting the phi, theta, and psi properties.
	@method EulerAngle#updateData
	@public
	@arg {Number} phi - New phi value.
	@arg {Number} theta - New theta value.
	@arg {Number} psi - New psi value.
	**/
	this.updateData = function(_phi, _theta, _psi)
	{
		this.phi   = _phi;
		this.theta = _theta;
		this.psi   = _psi;
	}
	
	/**
	A method for updating the phi, theta, and psi based on a {@link Quaternion} intance.
	@method EulerAngle#updateFromQuaternion
	@public
	@arg {Quaternion} q - Quaternion instance to update from.
	**/
	this.updateFromQuaternion = function(q)
	{
		var w = q.w, x = q.x, y = q.y, z = q.z;
		
		var w2 = w * w;
		var x2 = x * x;
		var y2 = y * y;
		var z2 = z * z;
		
		var tester = w * y - z * x;
		
		if (tester > 0.499999)
		{
			this.phi   = -2 * atan2(w, x);
			this.theta = Math.PI / 2;
			this.psi   = Math.PI;
			
			return;
		}
		else if (tester < -0.499999)
		{
			this.phi   = -2 * atan2(w, x);
			this.theta = -Math.PI / 2;
			this.psi   = Math.PI;
			
			return;
		}
		
		this.phi   = atan2(  2 * (w * x + y * z) , 1 - 2 * (x2 + y2) );
		this.theta = asin (  2 *  tester                             );
		this.psi   = atan2(  2 * (w * z + x * y) , 1 - 2 * (y2 + z2) );
	}
	
	/**
	A method for getting a {@link Quaternion} based on the current EulerAngle.
	@method EulerAngle#toQuaternion
	@public
	@returns {Quaternion} Returns a new {@link Quaternion} instance.
	**/
	this.toQuaternion = function()
	{
		var hPhi   = this.phi   / 2;
		var hTheta = this.theta / 2;
		var hPsi   = this.psi   / 2;
		
		var sin_hPhi   = sin(  hPhi), cos_hPhi   = cos(  hPhi);
		var sin_hTheta = sin(hTheta), cos_hTheta = cos(hTheta);
		var sin_hPsi   = sin(  hPsi), cos_hPsi   = cos(  hPsi);
		
		var w = cos_hPhi * cos_hTheta * cos_hPsi + sin_hPhi * sin_hTheta * sin_hPsi;
		var x = sin_hPhi * cos_hTheta * cos_hPsi - cos_hPhi * sin_hTheta * sin_hPsi;
		var y = cos_hPhi * sin_hTheta * cos_hPsi + sin_hPhi * cos_hTheta * sin_hPsi;
		var z = cos_hPhi * cos_hTheta * sin_hPsi - sin_hPhi * sin_hTheta * cos_hPsi;
		
		return new depthjs.Quaternion(w, x, y, z);
	}
	
	/**
	A method for setting the rotational values of a createjs.Matrix2D 3x3 matrix to mimic 3D rotation with affine transforms. Does not return a new createjs.Matrix2D, modifies the given one. Due to that it actually could be used with any matrix type class that uses the properties a, b, c, d, tx, and ty.
	@method EulerAngle#setMatrix
	@public
	@arg {createjs.Matrix2D} mtx - The createjs.Matrix2D to modify.
	@arg {Number} tx - A translation X to apply to the createjs.Matrix2D.
	@arg {Number} ty - A translation Y to apply to the createjs.Matrix2D.
	**/
	this.setMatrix = function(_mtx, _tx, _ty)
	{	
		var srz = sin(this.phi),   crz = cos(this.phi);
		var sry = sin(this.theta), cry = cos(this.theta);
		var srx = sin(this.psi),   crx = cos(this.psi);
		
		var crz_crx = crz * crx;
		var srz_crx = srz * crx;
		
		var sry_srx = sry * srx;
		
		var add_cry = sry_srx + cry;
		var sub_cry = sry_srx - cry;
		
		var x1 = -crz * sub_cry + srz_crx;
		var y1 = -srz * sub_cry - crz_crx;
		
		var x2 = -crz * add_cry + srz_crx;
		var y2 = -srz * add_cry - crz_crx;
		
		_mtx.a =  (x1 - x2) / 2;
		_mtx.b =  (y1 - y2) / 2;
		_mtx.c = -(x1 + x2) / 2;
		_mtx.d = -(y1 + y2) / 2;
		_mtx.tx = _tx || 0;
		_mtx.ty = _ty || 0;
	}
	
	/**
	Produces a new EulerAngle instance that is duplicate of the current one.
	@method EulerAngle#clone
	@public
	@returns {EulerAngle} Returns a new EulerAngle instance.
	**/
	this.clone = function()
	{
		return new depthjs.EulerAngle(this.phi, this.theta, this.psi);
	}
	
	/**
	A shortcut to copy the phi, theta, and psi values of another EulerAngle to this one.
	@method EulerAngle#copy
	@public
	@arg {EulerAngle} ea - The EulerAngle instance to copy values from.
	**/
	this.copy = function(ea)
	{
		this.phi   = ea.phi;
		this.theta = ea.theta;
		this.psi   = ea.psi;
	}
	
	/**
	Returns a String representation of the EulerAngle instance's values.
	@method EulerAngle#toString
	@public
	@returns {String} Returns a string with an object notation form of the phi, theta, and psi properties.
	**/
	this.toString = function()
	{
		return "{phi:"+this.phi+", theta:"+this.theta+", psi:"+this.psi+"}";
	}
	
	// hiking over math stuff for ease of writing...
	var asin  = Math.asin;
	var sqrt  = Math.sqrt;
	var atan2 = Math.atan2;
	var cos   = Math.cos;
	var sin   = Math.sin;
}

/////////////////////////////////////////////////////////////////////////////////////

/**
Each {@link DisplayObject} has a [transform3D]{@link DisplayObject3D#transform3D} property which is an instances of the Transform3D class. It holds properties for the coordinate and rotationsl data of the object in both local and world/global forms.
@class Transform3D
**/
depthjs.Transform3D = function()
{
	"use strict";
	
	/**
	The Transform3D instance's coordinates property is used for storing local coordinate data for calculations.
	@var Transform3D#coordinates {Point3D}
	@public
	**/
	/**
	The Transform3D instance's concatenatedCoordinates property is used for storing global coordinate data for calculations.
	@var Transform3D#concatenatedCoordinates {Point3D}
	@public
	**/
	this.coordinates = new depthjs.Point3D();
	this.concatenatedCoordinates = new depthjs.Point3D();
	/**
	The Transform3D instance's quaternion property is used for storing local quaternion based rotational data for calculations.
	@var Transform3D#quaternion {Quaternion}
	@public
	**/
	/**
	The Transform3D instance's concatenatedQuaterion property is used for storing global quaternion based rotational data for calculations.
	@var Transform3D#concatenatedQuaternion {Quaternion}
	@public
	**/
	this.quaternion = new depthjs.Quaternion();
	this.concatenatedQuaternion = new depthjs.Quaternion();
	/**
	The Transform3D instance's eulerAngle property is used for storing local euler angle based rotational data for calculations.
	@var Transform3D#eulerAngle {EulerAngle}
	@public
	**/
	/**
	The Transform3D instance's concatenatedEulerAngle property is used for storing global euler angle based rotational data for calculations.
	@var Transform3D#concatenatedEulerAngle {EulerAngle}
	@public
	**/
	this.eulerAngle = new depthjs.EulerAngle();
	this.concatenatedEulerAngle = new depthjs.EulerAngle();
	
	/**
	This method is a shortcut used to copy the concatenated coordinate and rotational data from one Transform3D instance to another.
	@method Transform3D#copyConcatenated
	@public
	@arg {Transform3D} t - The Transform3D to copy data from.
	**/
	this.copyConcatenated = function(t)
	{
		this.concatenatedCoordinates.copy( t.concatenatedCoordinates );
		this.concatenatedQuaternion.copy( t.concatenatedQuaternion );
		this.concatenatedEulerAngle.copy( t.concatenatedEulerAngle );
	}
	
	/**
	This method is a shortcut used to copy the inverted concatenated coordinate and rotational data from one Transform3D instance to another.
	@method Transform3D#copyInverseConcatenated
	@public
	@arg {Transform3D} t - The Transform3D to copy inverse data from.
	**/
	this.copyInverseConcatenated = function(t)
	{
		this.concatenatedCoordinates.copyInverse( t.concatenatedCoordinates );
		this.concatenatedQuaternion.copyInverse( t.concatenatedQuaternion );
		this.concatenatedEulerAngle.updateFromQuaternion( concatenatedQuaternion );
	}
	
	/**
	This method is a shortcut used to copy the local coordinate and rotational data from one Transform3D instance to another.
	@method Transform3D#copyLocal
	@public
	@arg {Transform3D} t - The Transform3D to copy data from.
	**/
	this.copyLocal = function(t)
	{
		this.coordinates.copy( t.coordinates );
		this.quaternion.copy( t.quaternion );
		this.eulerAngle.copy( t.eulerAngle );
	}
	
	/**
	A shortcut to copy the local and global coordinate and rotational data from one Transform3D instance to another.
	@method Transform3D#copy
	@public
	@arg {Transform3D} t - The Transform3D to copy data from.
	**/
	this.copy = function(t)
	{
		this.coordinates.copy( t.coordinates );
		this.concatenatedCoordinates.copy( t.concatenatedCoordinates );
		this.quaternion.copy( t.quaternion );
		this.concatenatedQuaternion.copy( t.concatenatedQuaternion );
		this.eulerAngle.copy( t.eulerAngle );
		this.concatenatedEulerAngle.copy( t.concatenatedEulerAngle );
	}
	
	/**
	Returns a String representation of all of the Transform3D instance's properties' values. Can be a bit verbose.
	@method Transform3D#toString
	@public
	@returns {String} Returns a string with an object notation form of the entire Transform3D.
	**/
	this.toString = function()
	{
		var val = '';
		val += "local coordinates: " + this.coordinates.toString() + "\n";
		val += "world coordinates: " + this.concatenatedCoordinates.toString() + "\n";
		val += "local quaternion : " + this.quaternion.toString() + "\n";
		val += "world quaternion : " + this.concatenatedQuaternion.toString() + "\n";
		val += "local euler angle: " + this.eulerAngle.toString() + "\n";
		val += "world euler angle: " + this.concatenatedEulerAngle.toString() + "\n";
		
		return val;
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////

/**
The DisplayObject3D class is an abstract class that serves as the base for all 3D capable elements to be used within a DepthJS {@link Stage3D} scene. Any class that inherits from DisplayObject3D also inherits from createjs.DisplayObject and therefore has all events and interactivity of any createjs.DisplayObject.
<br><br>
See <a href="http://createjs.com/docs/easeljs/classes/DisplayObject.html" target="_blank">createjs.DisplayObject</a> to understand the properties, methods, and events it inherits from createjs.DisplayObject.
@class DisplayObject3D
@extends createjs.DisplayObject
@abstract
**/
depthjs.DisplayObject3D = function()
{
	"use strict";
	
	// sorta extends createjs.DisplayObject
	// since this is never directly instantiated, it makes more sense for extensions of it to call this
	// extending by themselves if they need...or call a different one (like Container for example) if
	// that would be better for them
	
	var _x = this.x;
	var _y = this.y;
	var _z = 0;
	
	var _rotX = 0;
	var _rotY = 0;
	var _rotZ = 0;
	
	var dofBlur = new createjs.BlurFilter();
	var dofInArr = false;
	var effectArr = null;
		
	this._dirty = true;
	this._group = null;
	
	/**
	Each DisplayObject3D has a stage3D property that allows it to tell which stage it is currently in the display list of. Is null when not in a display list.
	@var DisplayObject3D#stage3D {Stage3D}
	@public
	@default null
	**/
	this.stage3D = null;
	
	/**
	The x property sets the x coordinate value for the DisplayObject3D instance.
	@var DisplayObject3D#x {Number}
	@public
	@default 0
	**/
	Object.defineProperty(this, 'x', {
		get: function() { return _x; },
		set: function(val) { if (val == _x) return; this._dirty = true; _x = val; }
	});
	
	/**
	The y property sets the y coordinate value for the DisplayObject3D instance.
	@var DisplayObject3D#y {Number}
	@public
	@default 0
	**/
	Object.defineProperty(this, 'y', {
		get: function() { return _y; },
		set: function(val) { if (val == _y) return; this._dirty = true; _y = val; }
	});
	
	/**
	The z property sets the z coordinate value for the DisplayObject3D instance.
	@var DisplayObject3D#z {Number}
	@public
	@default 0
	**/
	Object.defineProperty(this, 'z', {
		get: function() { return _z; },
		set: function(val) { if (val == _z) return; this._dirty = true; _z = val; }
	});
	
	/**
	The rotX property sets the x-axis rotation value for the DisplayObject3D instance in degrees.
	@var DisplayObject3D#rotX {Number}
	@public
	@default 0
	**/
	Object.defineProperty(this, 'rotX', {
		get: function() { return _rotX; },
		set: function(val) { if (val == _rotX) return; this._dirty = true; _rotX = val; }
	});
	
	/**
	The rotY property sets the y-axis rotation value for the DisplayObject3D instance in degrees.
	@var DisplayObject3D#rotY {Number}
	@public
	@default 0
	**/
	Object.defineProperty(this, 'rotY', {
		get: function() { return _rotY; },
		set: function(val) { if (val == _rotY) return; this._dirty = true; _rotY = val; }
	});
	
	/**
	The rotY property sets the y-axis rotation value for the DisplayObject3D instance in degrees.
	@var DisplayObject3D#rotZ {Number}
	@public
	@default 0
	**/
	Object.defineProperty(this, 'rotZ', {
		get: function() { return _rotZ; },
		set: function(val) { if (val == _rotZ) return; this._dirty = true; _rotZ = val; }
	});
	
	/**
	Contains the DipslayObject3D's local and global transform data.
	@var DisplayObject3D#transform3D {Transform3D}
	@public
	**/
	this.transform3D = new depthjs.Transform3D();
	
	// protected
	this.render = function(pDirty)
	{
		throw(new Error("::DepthJS Error:: DisplayObject3D can not be rendered, it is only a base class."));
	}
	
	// protected
	this.updateWorld = function()
	{
		var p3D = this._group || this.parent;
		
		var radX = _rotX * TO_RAD;
		var radY = _rotY * TO_RAD;
		var radZ = _rotZ * TO_RAD;
		
		this.transform3D.copyConcatenated( p3D.transform3D );
		this.transform3D.eulerAngle.updateData( radZ, radY, radX );
		this.transform3D.quaternion.updateFromEuler( this.transform3D.eulerAngle );
		this.transform3D.coordinates.updateData( _x, _y, _z );
		this.transform3D.concatenatedQuaternion.concatenate( this.transform3D.quaternion );
		this.transform3D.concatenatedEulerAngle.updateFromQuaternion( this.transform3D.concatenatedQuaternion );
	}
	
	// protected
	this.rotateCoords = function()
	{
		this.transform3D.concatenatedCoordinates.rotateAndUpdate( this.transform3D.coordinates, (this._group || this.parent).transform3D.concatenatedEulerAngle );
	}
	
	// protected
	this.rotateObject = function()
	{
		this.transformMatrix = this.transformMatrix || new createjs.Matrix2D();
		this.transform3D.concatenatedEulerAngle.setMatrix(this.transformMatrix, this.x, this.y);
	}
	
	// protected
	this.renderObject = function()
	{
		var zoom = this.stage3D.zoom;		
		var metaPoint = this.transform3D.concatenatedCoordinates;
		
		if (metaPoint.z > zoom)
			{ this.scaleX = 0; return; }
		
		var ax = metaPoint.x, ay = metaPoint.y, az = metaPoint.z;
		
		var dz      = zoom - az;
		var factor  = zoom / dz;
		var scaling = Math.pow(factor, this.stage3D.distortion);
		
		this.transformMatrix.tx = ax * factor;
		this.transformMatrix.ty = ay * factor;
		
		this.transformMatrix.scale(scaling, scaling);
	}
	
	// is kinda buggy, blurring just doesn't work well in createjs it seems, works for some things though
	this.renderDOF = function()
	{
		if (this.stage3D.depthOfField == null)
			return;
		
		if (!dofInArr)
		{
			if (effectArr == null) effectArr = this.filters || new Array();
			effectArr.push(dofBlur);
			dofInArr = true;
		}
		
		this.stage3D.depthOfField.render(this, dofBlur, effectArr);
	}
	
	this.renderADOF = function()
	{
		if (this.stage3D.alphaDepthOfField == null)
			return;
		
		this.stage3D.alphaDepthOfField.render(this);
	}
	
	// utility functions
	var cos = Math.cos;
	var sin = Math.sin;
	var PI = Math.PI;
	var TO_RAD = PI/180;
	var TO_DEG = 180/PI;
}

/////////////////////////////////////////////////////////////////////////////////////////////////

/**
The Group3D class acts as a container for 3D based elements. Any 3D elements inside a Group3D will move and rotate as the Group3D does in a forward kinematic fashion. Group3D instances can also contain other Group3D instances and create infinitely deep forward kinematics.
<br><br>
However, they still will z-sort against all other 3D elements in the {@link Stage3D} instance. In that respect the Group3D acts as a mathematical container only. However, it is still used like any other container with addChild, removeChild, etc. However, due to the fact that this is a 3D scene where the z-sorting is handled by an element's actual z coordinate there is no need for dealing with indexes. This means that even though this class acts like a normal createjs.Container in many ways methods such as addChildAt, removeChildAt, getChildAt, etc. which have to do with a child's index are invalid and will throw errors.
<br><br>
The above and the fact that z-sorting is still world-based and not just local to the container is the reason for the semantic difference in using the term "group" instead of "container".
<br><br>
For advanced understanding: in the CreateJS display list children of Group3D objects are actually contained by the root {@link Stage3D} container. That is how world z-sorting is accomplished. This also means that the bubbling of events, etc. will come frome there, not from the Group3D. It is a poor idea to add events directly to the Group3D instance.
@class Group3D
@extends DisplayObject3D
**/
depthjs.Group3D = function()
{
	"use strict";
	
	this.DisplayObject_constructor(); // extends createjs.DisplayObject
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	
	// groups 3D objects together in its own pseudo-display list. Technically
	// easeljs will consider all children of groups to be direct children of
	// the 3d stage, the Group3D only mathematically handles forward kinematics
	// for the objects. It is also for 3D depthjs objects only. For an object
	// container of 2D objects within the 3D world look to Container3D
	
	// internal vars
	this._children = new Array();
	this._container = null;
	this.addMode = false;
	this._groups = new Array();
	
	// private
	this.onAdded = function(e)
	{
		var targ = e.target;
		targ._container = targ.parent;
		
		if (targ._container._groups.indexOf(targ) == -1)
			targ._container._groups.push(targ);
		
		targ.addMode = true; // so it doesn't just remove them as you add them
		var i = 0, t = targ._children.length;
		for (i=0; i<t; i++)
			targ._container.addChild(targ._children[i]);
		targ.addMode = false;
	}
	
	// private
	this.onRemoved = function(e)
	{
		var targ = e.target;
		if (targ._container == null)
			return;
		
		var i = targ._container._groups.indexOf(targ);
		if (i != -1)
			targ._container._groups.splice(i, 1);
		
		var t = targ._children.length;
		for (i=0; i<t; i++)
			targ._container.removeChild(targ._children[i]);
		
		targ._container = null;
	}
	
	this.addEventListener('added', this.onAdded);
	this.addEventListener('removed', this.onRemoved);
	this.visible = false; // so it takes none of easel's rendering speed away
	
	// following are all overrides to mimic easel display list adding/removing
	
	/**
	addChild allows objects to be added to this Group3D. Note: likewise, a Group3D instance is added to another Group3D or to the {@link Stage3D} via those instances' addChild methods as well. addChild may take a singular value to add or may be given many such as instance.addChild(one, two, three, four);
	@method Group3D#addChild
	@public
	@arg {DisplayObject3D} - Any object that inherits from DisplayObject3D may be added.
	@returns {DisplayObject3D} Returns the DisplayObject3D that was added, or the last that was added if multiple were added at once.
	**/
	this.addChild = function(obj)
	{
		// handle if adding multiple at once
		if (arguments.length > 1)
		{
			var returnVal = null;
			for (var i=0,ii=arguments.length; i<ii;i++)
				returnVal = this.addChild(arguments[i]);
			
			return returnVal;
		}
		
		if (obj._group && obj._group != this)
			obj._group.removeChild(obj);
		
		this.addMode = true;
		if (this._container)
			this._container.addChild(obj);
		this.addMode = false;
		
		obj._group = this;
		
		if (this._children.indexOf(obj) == -1)
			this._children.push(obj);
		
		return obj;
	}
	
	/**
	getChildByName allows you to get a child of the Group3D by its name property.
	@method Group3D#getChildByName
	@public
	@arg {String} - The String name to look for.
	@returns {DisplayObject3D} Returns a the DisplayObject3D found if it is found. Returns null of none found.
	**/
	this.getChildByName = function(str)
	{
		// TODO: is this shortcut effective?
		/*
		if (this._container)
			return this._container.getChildByName(str);
		*/
		
		var i = 0, t = this._children.length;
		for (i=0; i<t; i++)
			if (this._children[i].name == str)
				return this._children[i];
		
		return null;
	}
	
	/**
	removeChild allows objects that were added via [addChild]{@link Group3D#addChild} to be removed. removeChild may take a singular value to remove or may be given many such as instance.removeChild(one, two, three, four);
	@method Group3D#removeChild
	@public
	@arg {DisplayObject3D} - Any object that inherits from DisplayObject3D and has been added may be removed.
	@returns {Boolean} Returns a Boolean value for if the object was removed (false if it was not in the display list to be removed), or the result for the last that was removed if multiple were removed at once.
	**/
	this.removeChild = function(obj)
	{
		// handle if removing multiple at once
		if (arguments.length > 1)
		{
			var returnVal = null;
			for (var i=0,ii=arguments.length; i<ii;i++)
				returnVal = this.removeChild(arguments[i]);
			
			return returnVal;
		}
		
		obj._group = null;
		
		if (this._container)
			this._container.removeChild(obj);
		
		var i = this._children.indexOf(obj);
		if (i != -1)
			this._children.splice(i, 1);
		
		return obj;
	}
	
	var super_getChildIndex = this.getChildIndex;
	this.getChildIndex = function(obj)
	{
		// TODO: should this even try, or just throw an error for doing a sorting/index related thing?
		
		// for now, calling this illegal
		throw(new Error('getChildAt does not work on 3D groups!'));
		
		/*
		var i = this._children.indexOf(obj);
		if (this._container && i != -1)
			return this._container.getChildIndex(obj);
		else if (i != -1)
			return i;
		else
			return super_getChildIndex(obj); // will throw the appropriate error
		*/
	}
	
	/**
	contains allows you to check if a DisplayObject3D is contained (has been added via addChild) by the Group3D
	@method Group3D#contains
	@public
	@arg {DisplayObject3D} - The object to test for.
	@returns {Boolean} Returns a Boolean value for whether the Group3D contains the object or not.
	**/
	this.contains = function(obj)
	{
		return this._children.indexOf(obj) != -1;
	}
	
	this.removeChildAt = function(i)
	{
		throw(new Error('removeChildAt does not work on 3D groups!'));
	}
	
	this.getChildAt = function(i)
	{
		throw(new Error('getChildAt does not work on 3D groups!'));
	}
	
	this.addChildAt = function(obj, i)
	{
		throw(new Error('addChildAt does not work on 3D groups!'));
	}
	
	// protected
	this.updateGroupData = function(pDirty)
	{
		pDirty = pDirty !== false;
		var i, t;
		
		if (!this._dirty && !pDirty)
		{
			// give any child groups a chance to render even if this isn't dirty
			t = this._groups.length;
			for (i=0; i<t; i++)
				this._groups[i].updateGroupData(false);
			return;
		}
		
		this.updateWorld();
		this.rotateCoords();
		
		t = this._groups.length;
		for (i=0; i<t; i++)
			this._groups[i].updateGroupData(pDirty || this._dirty);
		
		t = this._children.length;
		for (i=0; i<t; i++)
			this._children[i]._dirty = true;
		
		this._dirty = false;
	}
	
	// protected
	this.render = function(pDirty)
	{
		// the actual parent handles sorting and rendering, so override the DisplayObject3D render and leave blank
	}
}

createjs.extend(depthjs.Group3D, createjs.DisplayObject);
depthjs.Group3D = createjs.promote(depthjs.Group3D, "DisplayObject");

//////////////////////////////////////////////////////////////////////////////////////////////////

/**
PlaneLockable is an abstract class that any class that allows its rotational values to be locked forward via a lockFacingFront property inherits from. Note: that is not the same as locking the rotations to 0. They will face forward even if a parent Group3D is rotated. Basically by setting the lockFacingFront to true all ability to rotate along any axis is removed and it only moves its location in 3D space. Only classes that also inherit from DisplayObject3D may inherit from this class.
@class PlaneLockable
@abstract
**/
depthjs.PlaneLockable = function()
{
	"use strict";
	
	// WARNING: this class is only intended to extend other classes that are already
	// extending CreateJS display objects and then DisplayObject3D!
	
	// adds the lockFacingFront property and the render method for standard 2D plane type objects
	/**
	Allows locking of the DisplayObject3D facing forward at all times if set to true, regardless or local or global rotation.
	@var PlaneLockable#lockFacingFront {Boolean}
	@public
	@default false
	**/
	this.lockFacingFront = false;
	
	this.render = function(pDirty)
	{
		pDirty = pDirty !== false;
		
		if (!this._dirty && !pDirty)
			return;
		
		this._dirty = false;
		
		this.updateWorld();
		this.rotateCoords();
		if (!this.lockFacingFront)
			this.rotateObject();
		else if (this.transformMatrix)
			this.transformMatrix.setValues(1,0,0,1,0,0);
		else
			this.transformMatrix = new createjs.Matrix2D();
		this.renderObject();
		this.renderDOF();
		this.renderADOF();
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////

/**
Sortable is an abstract class that any class that does z-sorting inherits from. This includes {@link Stage3D} and the {@link OrthoPrimitive} class. Note that this does NOT include the {@link Group3D} class. {@link Group3D} acts as a mathematical container but allows all its children to be sorted against all others on stage. Therefore it pushes its z-sorting to the root {@link Stage3D} instance.
<br><br>
There are no externally usable methods or properties in this class. It is solely for use as an abstract class where protected methods and properties are inherited for use.
@class Sortable
@abstract
**/
depthjs.Sortable = function()
{
	"use strict";
	
	// WARNING: this class is only intended to extend other classes that are already
	// extending Container and then DisplayObject3D!
	
	// this gets used to add render/sorting ability to objects intended as containers/
	// of other 3D objects, like Stage3D and OrthoPrimitive3D (not Group3D, which is solely
	// a mathematical container, not an actual display list one, the root display list type
	// container does the sorting for all its child groups).
	
	// protected
	this.zIndex = null;
	
	this.render = function(pDirty)
	{
		pDirty = pDirty !== false;
		var i, t;
		
		if (!this._dirty && !pDirty)
		{
			// give any child groups a chance to render even if this isn't dirty
			t = this._groups.length;
			for (i=0; i<t; i++)
				this._groups[i].updateGroupData(false);
			this.sort(false); // still needs to sort so children can move on their own
			return;
		}
		// don't clear _dirty until AFTER sorting
		
		this.updateWorld();
		this.rotateCoords();
		
		t = this._groups.length;
		for (i=0; i<t; i++)
			this._groups[i].updateGroupData(pDirty || this._dirty);
		
		this.sort(pDirty);
		this._dirty = false;
	}
	
	// protected
	this.sort = function(pDirty)
	{
		pDirty = pDirty !== false;
		
		var t = this.numChildren;
		this.zIndex = new Array(t);
		
		for (var i = 0; i < t; i++)
		{
			var obj = this.getChildAt(i);
			obj.render(pDirty || this._dirty);
			//this.zIndex[i] = obj;
		}
		
		this.children.sort(function(a,b){ return a.transform3D.concatenatedCoordinates.z - b.transform3D.concatenatedCoordinates.z; });
		
		// TODO: all usage of zIndex may be able to be removed since direct access of 'children' is available
		//var n = this.zIndex.length;
		//for each (var so in this.zIndex)
			//this.setChildIndex(so, --n);
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////

/**
All 3D elements to be rendered are to be added to a Stage3D instance. Note that the Stage3D does NOT replace the createjs.Stage. It goes inside of it like a normal CreateJS display object. Even though it inherits from DisplayObject3D it should be treated like a 2D object on the CreateJS stage as far as its own positioning/rotating goes. Any z, rotX, rotY, and rotZ properties are not intended to function; only x and y should be used. If you want a container for 3D elements that you can move and rotated in 3D space then see {@link Group3D}.
<br><br>
Also note that a Stage3D needs to be updated each frame. If autoRender is used (as is default) it will just constantly update. This is not as taxing as it would seem since it uses a diry/clean rendering system. For slightly better performance you can update manually as needed using the [render]{@link Stage3D#render} method.
<br><br>
See <a href="http://createjs.com/docs/easeljs/classes/Container.html" target="_blank">createjs.Container</a> to understand the properties, methods, and events it inherits from createjs.Container.
@class Stage3D
@extends createjs.Container
@extends DisplayObject3D
@extends Sortable
@arg {Boolean} [autoRender=true] - Shortcut to the set [autoRender]{@link Stage3D#autoRender} property.
**/
depthjs.Stage3D = function(autoRender)
{
	"use strict";
	
	this.Container_constructor(); // extends createjs.Container
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	depthjs.Sortable.call(this); // extends depthjs.Sortable
	
	// this class DOES NOT replace the normal easel stage. It is simply the root
	// container for 3D rendered objects. You add a Stage3D instance to your easel
	// stage. The Stage3D instance ONLY is to directly contain depthjs defined display
	// objects. To utilize normal easel display elements put them inside a Container3D
	// instance and then use that instance in the 3D world.
	
	// if argument autoRender is true or isn't defined (or if the property gets toggled on)
	// then a 'tick' listener will be added which will render any dirty parts of the 3D scene
	// automatically every time the easel stage's stage.update() is called (it will update the 3d
	// right before the stage update
	autoRender = typeof autoRender !== 'undefined' ? autoRender : true;
	
	var _autoRender = autoRender;
	// var renderEvent = new Event('3d render'); // gone for 1.0.1 due to not working in IE
	this._groups = new Array();
	
	/**
	zoom affects how objects are scaled as they move on the z-axis. Experiment to get the effect that works for your use.
	@var {Number} Stage3D#zoom
	@public
	@default 5000
	**/
	/**
	distortion affects how the location of objects are distorted (lesser for further away, more for closer) as they move on the z-axis. Experiment to get the effect that works for your use.
	@var {Number} Stage3D#distortion
	@public
	@default 6
	**/
	// rendering properties
	this.zoom = 5000;
	this.distortion = 6;
	
	/**
	Depth of field is an effect by which objects appear blurrier the further they are from the focus of a camera. The {@link DepthOfField} class can mimic this effect in DepthJS. To do so set this property to a {@link DepthOfField} instance. Use null for none. Blurriness in CreateJS is not the best nor easy on the system. Consider using the [alphaDepthOfField]{@link Stage3D#alphaDepthOfField} property instead.
	@var {DepthOfField} Stage3D#depthOfField
	@public
	@default null
	**/
	/**
	Depth of field is an effect by which objects appear blurrier the further they are from the focus of a camera. The {@link AlphaDepthOfField} class can mimic this effect in DepthJS except with alpha instead of blur. To do so set this property to an {@link AlphaDepthOfField} instance. Use null for none.
	@var {AlphaDepthOfField} Stage3D#alphaDepthOfField
	@public
	@default null
	**/
	// rendering effects
	this.depthOfField = null;
	this.alphaDepthOfField = null;
	
	/**
	isStage3D is a read-only property to easily determine if an object is a Stage3D instance.
	@var {Boolean} Stage3D#isStage3D
	@public
	@readonly
	@default true
	**/
	// simple method isStage3D for testing if we're on a Stage3D object or object that extends from Stage3D
	Object.defineProperty(this,'isStage3D',{get:function(){return true;},set:function(v){}});
	
	/**
	In Stage3D instances the DisplayObject3D property stage3D always should read as the Stage3D instance itself.
	@var {Stage3D} Stage3D#stage3D
	@public
	@readonly
	@default this
	**/
	this.stage3D = this;
	
	/**
	@var Stage3D#transform3D
	@ignore
	**/
	var c = this.transform3D.coordinates;
	c.x = 0; c.y = 0; c.z = 0;
	this.transform3D.concatenatedCoordinates.copy( c );
	
	var e = this.transform3D.eulerAngle;
	e.phi = 0; e.theta = 0; e.psi = 0;
	this.transform3D.concatenatedEulerAngle.copy( e );
	
	var q = this.transform3D.quaternion;
	q.w = 1; q.x = 0; q.y = 0; q.z = 0;
	this.transform3D.concatenatedQuaternion.copy( q );
	
	// ignore 3D transforms on 3D, it has them but doesn't use them
	/**
	@var Stage3D#z
	@ignore
	**/
	/**
	@var Stage3D#rotX
	@ignore
	**/
	/**
	@var Stage3D#rotY
	@ignore
	**/
	/**
	@var Stage3D#rotZ
	@ignore
	**/
	
	// set 2D like docs for the x and y
	/**
	The instance's x coordinate in normal CreateJS 2D space.
	@var {Number} Stage3D#x
	@public
	@default 0
	**/
	/**
	The instance's y coordinate in normal CreateJS 2D space.
	@var {Number} Stage3D#y
	@public
	@default 0
	**/
	
	/**
	Turn on/off automatic rendering. When true this will update the stage on every frame. Because of the engine's dirty/clean rendering system this is not very taxing. However, if you wish to update it yourself see the [render]{@link Stage3D#render} method. This is also set by constructor argument from instantiation.
	@var {Number} Stage3D#autoRender
	@public
	@default true
	**/
	Object.defineProperty(this, 'autoRender', {
		get: function() { return _autoRender; },
		set: function(val) {
			if (!_autoRender && val)
				this.addEventListener('tick', renderStage);
			else if (_autoRender && !val)
				this.removeEventListener('tick', renderStage);
				
			_autoRender = val;
		}
	});
	
	/**
	addChild allows objects to be added to this Stage3D instance. addChild may take a singular value to add or may be given many such as instance.addChild(one, two, three, four);
	@method Stage3D#addChild
	@public
	@arg {DisplayObject3D} - Any object that inherits from DisplayObject3D may be added.
	@returns {DisplayObject3D} Returns the DisplayObject3D that was added, or the last that was added if multiple were added at once.
	**/
	this.super_addChild = this.addChild;
	this.addChild = function(obj)
	{
		// handle if adding multiple at once
		if (arguments.length > 1)
		{
			var returnVal = null;
			for (var i=0,ii=arguments.length; i<ii;i++)
				returnVal = this.addChild(arguments[i]);
			
			return returnVal;
		}
		
		obj.stage3D = this;
		
		var g = obj._group;
		if (g && !g.addMode)
			g.removeChild(obj);
		
		return this.super_addChild(obj);
	}
	
	/**
	removeChild allows objects that were added via [addChild]{@link Stage3D#addChild} to be removed. removeChild may take a singular value to remove or may be given many such as instance.removeChild(one, two, three, four);
	@method Stage3D#removeChild
	@public
	@arg {DisplayObject3D} - Any object that inherits from DisplayObject3D and has been added may be removed.
	@returns {Boolean} Returns a Boolean value for if the object was removed (false if it was not in the display list to be removed), or the result for the last that was removed if multiple were removed at once.
	**/
	this.super_removeChild = this.removeChild;
	this.removeChild = function(obj)
	{
		// handle if removing multiple at once
		if (arguments.length > 1)
		{
			var returnVal = null;
			for (var i=0,ii=arguments.length; i<ii;i++)
				returnVal = this.removeChild(arguments[i]);
			
			return returnVal;
		}
		
		obj.stage3D = null;
		return this.super_removeChild(obj);
	}
	
	// meant to be empty so they don't do anything
	this.updateWorld = function() { }
	this.rotateCoords = function() { }
	
	// private
	var renderStage = function(e)
	{
		e.target.render(false);
		// e.target.dispatchEvent(renderEvent); // gone for 1.0.1 due to not working in IE
	}
	
	// protected // TODO: is this even used anymore?
	// renders everything as if is dirty
	this.renderAll = function()
	{
		this.render(true);
		// this.dispatchEvent(renderEvent); // gone for 1.0.1 due to not working in IE
	}
	
	/**
	Stage3D's update method updates the locations/rotations of everything in the display list if their locations/rotation values are dirty (i.e. are not the same as the last render/update). This method only needs to be used if not using autoRender.
	@method Stage3D#update
	@public
	**/
	this.update = function()
	{
		this.render(false);
	}
	
	// must put at bottom otherwise renderStage isn't defined yet
	if (autoRender) this.addEventListener('tick', renderStage);
	
	// overrides the setters
	this.__set_x = function(val) {}
	this.__set_y = function(val) {}
	this.__set_z = function(val) {}
	this.__set_rotX = function(val) {}
	this.__set_rotY = function(val) {}
	this.__set_rotZ = function(val) {}
}

createjs.extend(depthjs.Stage3D, createjs.Container);
depthjs.Stage3D = createjs.promote(depthjs.Stage3D, "Container");

////////////////////////////////////////////////////////////////////////////////////////////

/**
Shape3D is a 3D element meant to be added to a {@link Stage3D} or {@link Group3D}. It is meant to be primarily used for its graphics property which it inherits from the createjs.Shape class. Basically use it in a {@link Stage3D} in 3D in the way you'd use a createjs.Shape object in a createjs.Stage object in 2D.
<br><br>
See <a href="http://createjs.com/docs/easeljs/classes/Shape.html" target="_blank">createjs.Shape</a> to understand the properties, methods, and events it inherits from createjs.Shape.
@class Shape3D
@extends createjs.Shape
@extends DisplayObject3D
@extends PlaneLockable
@arg {createjs.Graphics} [graphics=null] - Shortcut to the set a createjs.Graphics property on the Shape3D instance.
**/
depthjs.Shape3D = function(graphics)
{
	"use strict";
	
	this.Shape_constructor(graphics); // extends createjs.Shape
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	depthjs.PlaneLockable.call(this); // extends depthjs.PlaneLockable
}

createjs.extend(depthjs.Shape3D, createjs.Shape);
depthjs.Shape3D = createjs.promote(depthjs.Shape3D, "Shape");

///////////////////////////////////////////////////////////////////////////////////////////////

/**
Container3D is a 3D element meant to be added to a {@link Stage3D} or {@link Group3D}. POINT OF CONFUSION: it is meant to contain normal CreateJS 2D objects (like Shape, and Bitmap, etc) NOT other 3D elements. To contain other 3D elements to move about in 3D space see {@link Group3D}. This class is meant to be primarily used for its containing properties which it inherits from the createjs.Container class. Basically use it in a {@link Stage3D} in 3D in the way you'd use a createjs.Container object in a createjs.Stage object in 2D.
<br><br>
Furthermore this is the means by which you'd use other CreateJS objects in DepthJS like Bitmap, BitmapText, Sprite, etc. You'd use addChild to put it in a Container3D and then the Container3D would be what's added to the 3D world.
<br><br>
See <a href="http://createjs.com/docs/easeljs/classes/Container.html" target="_blank">createjs.Container</a> to understand the properties, methods, and events it inherits from createjs.Container.
@class Container3D
@extends createjs.Container
@extends DisplayObject3D
@extends PlaneLockable
**/
depthjs.Container3D = function()
{
	"use strict";
	
	this.Container_constructor(); // extends createjs.Container
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	depthjs.PlaneLockable.call(this); // extends depthjs.PlaneLockable
	
	// this class is designed to contain ONLY normal 2D objects. It is a 2D plane
	// full of normal 2D objects, but that plane itself can move/rotate in 3D space
	// to contain/group 3D objects together in a forward kinematic way, look to the
	// Group3D class.
}

createjs.extend(depthjs.Container3D, createjs.Container);
depthjs.Container3D = createjs.promote(depthjs.Container3D, "Container");

///////////////////////////////////////////////////////////////////////////////////////////////

/**
Sprite3D basically is a 2D container moving around in the 3D world that always faces direct front. Instead of rotating, it moves through images in a spritesheet that represent a 360 degree rotation of an object (such as a 360 degree render) around either the X or Y axis. In this way we have a 3D rendering that can be rotated in DepthJS.
<br><br>
See <a href="http://createjs.com/docs/easeljs/classes/Container.html" target="_blank">createjs.Container</a> to understand the properties, methods, and events it inherits from createjs.Container.
<br><br>
Due to some complexity in the way 3D euler angles work (i.e. 2 different combos of rotX, rotY, rotZ can technically lead to the same exact orientation) using the true concatenated 3D angles doesn't work so hot. A good way to approximate for these purposes, however, is to just add the local rotY of the child and every parent (or rotX if that's what you're using) just for figuring what frame the Sprite3D should be on for its rotation. It's not technically perfectly accurate for complex usage, but for most usage it works fine.
@class Sprite3D
@extends createjs.Container
@extends DisplayObject3D
@arg spriteSheet {createjs.SpriteSheet} A <a href="http://createjs.com/docs/easeljs/classes/SpriteSheet.html" target="_blank">createjs.SpriteSheet</a> instance to use for the Sprite3D.
**/
depthjs.Sprite3D = function(spriteSheet)
{
	"use strict";
	
	this.Container_constructor(); // extends createjs.Container
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	
	/**
	The <a href="http://createjs.com/docs/easeljs/classes/Sprite.html" target="_blank">createjs.Sprite</a> instance used by the Sprite3D class.
	@var {createjs.Sprite} Sprite3D#sprite
	@public
	**/
	this.sprite = new createjs.Sprite(spriteSheet);
	this.sprite.stop();
	this.addChild(this.sprite);
	
	/**
	Offsets the Sprite3D zero rotation with your animation. Example: offsetting by 180 would make the middle of your animation be considered the 0 degree showing frame. Note: never set to more than + or - your [rotationRange]{@link Sprite3D#rotationRange}. Can be positive or negative.
	@var {Number} Sprite3D#rotationOffset
	@public
	@default 0
	**/
	this.rotationOffset = 0; // never set to more or less than the + and - of your rotationRange (normally 360)
	
	/**
	For load speed purposes if you're not using the full 360 degree rotation of your object you can tell Sprite3D how many degrees its supposed to cover when dividing up your animation sprite. Never set to more than 360. Positive numbers only.
	@var {Number} Sprite3D#rotationRange
	@public
	@default 360
	**/
	this.rotationRange = 360; // never set to more than 360
	
	/**
	Set this to true if your animation is around the x-axis instead of y-axis.
	@var {Boolean} Sprite3D#useRotX
	@public
	@default false
	**/
	this.useRotX = false; // normally uses rotY, set this to true to use rotX instead
	
	/**
	A value of true inverts the axis of rotation in case your 3D sprite turns out to have been animated backwards to what the Sprite3D class expects.
	@var {Boolean} Sprite3D#inverse
	@public
	@default false
	**/
	this.inverse = false; // if your animation of 3D rotation is backwards, turn this to true
	
	this.render = function(pDirty)
	{
		pDirty = pDirty !== false;
		
		if (!this._dirty && !pDirty)
			return;
		
		this._dirty = false;
		
		this.updateWorld();
		this.rotateCoords();
		if (this.transformMatrix)
			this.transformMatrix.setValues(1,0,0,1,0,0);
		else
			this.transformMatrix = new createjs.Matrix2D();
		this.renderObject();
		this.renderSprite();
		this.renderDOF();
		this.renderADOF();
	}
	
	var numOfFrames = 0;
	this.renderSprite = function()
	{
		// set the min and max range that the spritesheet is meant to cover
		var min = this.rotationOffset;
		var max = min + this.rotationRange - 1;
		
		numOfFrames = numOfFrames > 0 ? numOfFrames : this.sprite.spriteSheet.getNumFrames();
		if (numOfFrames == 0) return;
		
		// get how many degrees of movement each sprite frame covers
		var div = this.rotationRange / numOfFrames;
		
		// get current rotation from 0 to 359 then minus the offset from it
		var rot = addParentRotation.call(this, (this.useRotX?this.rotX:this.rotY), this) % 360;
		if (rot < 0) rot += 360;
		rot = rot - min;
		
		// hold within the min and max
		if (rot < min) rot = min; if (rot > max) rot = max;
		
		// get the new index
		var newIndex = Math.round((rot - (rot % div)) / div);
		
		// move the sprite to that index
		this.sprite.gotoAndStop(this.inverse ? numOfFrames-newIndex : newIndex);
	}
	
	// recursive, keeps calling itself until it gets to the Stage3D instance and
	// then returns the total
	var addParentRotation = function(totalSoFar, obj)
	{
		var p = obj._group ? obj._group : obj.parent;
		
		if (p.isStage3D)
			return totalSoFar;
			
		return addParentRotation.call(this, totalSoFar+(this.useRotX?p.rotX:p.rotY), p);
	}
}

createjs.extend(depthjs.Sprite3D, createjs.Container);
depthjs.Sprite3D = createjs.promote(depthjs.Sprite3D, "Container");

/////////////////////////////////////////////////////////////////////////////////////////////

/**
PaperContainer3D is an otherwise normal {@link Container3D} except that you can set a front and back property which will show one when facing forward and the other when backwards. Basically making a two sided plane.
<br><br>
See <a href="http://createjs.com/docs/easeljs/classes/Container.html" target="_blank">createjs.Container</a> to understand the properties, methods, and events it inherits from createjs.Container.
@class PaperContainer3D
@extends createjs.Container
@extends DisplayObject3D
@arg front {createjs.DisplayObject} - Any type of CreateJS 2D display object to show as the front side.
@arg back {createjs.DisplayObject} - Any type of CreateJS 2D display object to show as the back side.
**/
depthjs.PaperContainer3D = function(a_front, a_back)
{
	"use strict";
	
	this.Container_constructor(); // extends createjs.Container
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	
	var _front = null;
	var _back = null;
	var _frontFacing = true;
	
	this.autoFlipBack = true;
	
	/**
	Any CreateJS 2D display object to show as the front side.
	@var {createjs.DisplayObject} PaperContainer3D#front
	@public
	@default null
	**/
	Object.defineProperty(this, 'front', {
		get: function() { return _front; },
		set: function(val) {
			if (_front && this.contains(_front)) this.removeChild(_front);
			val.visible = _frontFacing;
			_front = val;
			this.addChild(_front);
		}
	});
	
	/**
	Any CreateJS 2D display object to show as the back side.
	@var {createjs.DisplayObject} PaperContainer3D#back
	@public
	@default null
	**/
	Object.defineProperty(this, 'back', {
		get: function() { return _back; },
		set: function(val) {
			if (_back && this.contains(_back)) this.removeChild(_back);
			val.visible = !_frontFacing;
			_back = val;
			if (this.autoFlipBack) _back.scaleX = -1;
			this.addChild(_back);
		}
	});
	
	if (typeof a_front !== 'undefined') this.front = a_front;
	if (typeof a_back  !== 'undefined') this.back  = a_back;
	
	/**
	Read only true or false telling you whether or not the PaperContainer3D instance is currently considered to be front or back facing according to the rendering engine. It is recommended that you use this as opposed to just checking its rotation since this reflects how its showing in the global scheme. It's {@link Group3D} could be the one with the rotation and then this objects rotations could still all be zero. This lets you know anyway.
	@var {Boolean} PaperContainer3D#frontFacing
	@public
	@readonly
	**/
	Object.defineProperty(this, 'frontFacing', {
		get: function() { return _frontFacing; },
		set: function(val) { } // read only
	});
	
	this.render = function(pDirty)
	{
		pDirty = pDirty !== false;
		
		if ((!this._dirty && !pDirty) || !this.visible)
			return;
			
		this._dirty = false;
		
		this.updateWorld();
		this.rotateCoords();
		this.rotateObject();
		this.renderObject();
		this.renderDOF();
		this.renderADOF();
		this.determineFace();
	}
	
	var p1, p2, p3;
	this.determineFace = function()
	{
		// winding method credit to senocular...works very well, and quick too, thanks bud!
		p1 = this.localToGlobal(0,0);
		p2 = this.localToGlobal(100,0);
		p3 = this.localToGlobal(0,100);
		_frontFacing = ((p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x)) > 0;
		
		if (_back) _back.visible = !_frontFacing;
		if (_front) _front.visible = _frontFacing;
	}
}

createjs.extend(depthjs.PaperContainer3D, createjs.Container);
depthjs.PaperContainer3D = createjs.promote(depthjs.PaperContainer3D, "Container");

////////////////////////////////////////////////////////////////////////////////////////////////////

/**
DepthJS utlizes CreateJS's affine transformations to simulate 3D. Therefore the transformations on the objects are technically orthographic, but their positions in 3D space represent non-orthographic rendering. This creates a nice 3D effect even with just affine transformations...but leads to edges not fully lining up on things, etc. To make something as precise as a primitive you'd need to render the children of that primitive (i.e. the faces) completely orthographically. That's what the OrthoPrimitive class does. It takes {@link OrthoFaceShape} and {@link OrthoFaceContainer} class objects as children (which correspond in functionality with the {@link Shape3D} and {@link Container3D} classes) and renders them orthographically allowing you to set up as precise primitives. They also z-sort as their own display list, meaning children of the OrthoPrimitive only z-sort against each other. The OrthoPrimitive itself then z-sorts against other objects on stage as a whole. That way other 3D elements are either completely in front of or behind it, not splitting its faces.
<br><br>
Its functionality is no different than any {@link Group3D} object except that it takes events normally (unline Group3D elements). Add children, remove them, etc (as long as they're {@link OrthoFaceShape} and {@link OrthoFaceContainer} class objects). The difference is that you can be precise about those children's placement and build primitives out of them.
<br><br>
See <a href="http://createjs.com/docs/easeljs/classes/Container.html" target="_blank">createjs.Container</a> to understand the properties, methods, and events it inherits from createjs.Container.
@class OrthoPrimitive
@extends createjs.Container
@extends DisplayObject3D
@extends Sortable
**/
depthjs.OrthoPrimitive = function()
{
	"use strict";
	
	this.Container_constructor(); // extends createjs.Container
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	depthjs.Sortable.call(this); // extends depthjs.Sortable
	
	/**
	addChild allows objects to be added to this OrthoPrimitive. addChild may take a singular value to add or may be given many such as instance.addChild(one, two, three, four);
	@method OrthoPrimitive#addChild
	@public
	@arg obj - The object to be be added.
	@returns Returns the object that was added, or the last that was added if multiple were added at once.
	**/
	
	/**
	removeChild allows objects that were added via [addChild]{@link OrthoPrimitive#addChild} to be removed. removeChild may take a singular value to remove or may be given many such as instance.removeChild(one, two, three, four);
	@method OrthoPrimitive#removeChild
	@public
	@arg obj - The object that has been added and is to be removed.
	@returns {Boolean} Returns a Boolean value for if the object was removed (false if it was not in the display list to be removed), or the result for the last that was removed if multiple were removed at once.
	**/
	
	this.render = function(pDirty)
	{
		pDirty = pDirty !== false;
		
		if (!this._dirty && !pDirty)
			{ this.sort(pDirty); return; } // still needs to sort so children can move on their own
		// don't clear _dirty until AFTER sorting
		
		this.updateWorld();
		this.rotateCoords();
			
		this.sort(pDirty);
		this._dirty = false;
		
		// Since inside the OrthoPrimitive the rendering is orthographic, and normally scaling happens on the objects,
		// not the containers, in order to have the OrthoPrimitive scale, it needs to override this render function and
		// add the code below.
		
		var metaZ = this.transform3D.concatenatedCoordinates.z;
		var zoom = this.stage3D.zoom;
		
		if (metaZ > zoom)
			{ this.scaleX = 0; return; }
		
		var dz      = zoom - metaZ;
		var factor  = zoom / dz;
		var scaling = Math.pow(factor, this.stage3D.distortion);
		
		this.transformMatrix = this.transformMatrix || new createjs.Matrix2D();
		this.transformMatrix.a = this.transformMatrix.d = scaling;
		
		// normally we would NOT do depth of field on a container since it would just mess with the dof on it's children
		// but since these are faces of the same object rendering dof on each would be bad, so Face3D doesn't do dof and
		// OrthoPrimitive does 
		
		// blurring is pretty buggy on createjs...but unfortunately blurring a container of children is even more buggy...just turning this off
		//this.renderDOF();
		this.renderADOF();
	}
}

createjs.extend(depthjs.OrthoPrimitive, createjs.Container);
depthjs.OrthoPrimitive = createjs.promote(depthjs.OrthoPrimitive, "Container");

////////////////////////////////////////////////////////////////////////////////////////

/**
The {@link Container3D} equivalent for usage inside the {@link OrthoPrimitive} class. See those two classes.
@class OrthoFaceContainer
@extends createjs.Container
@extends DisplayObject3D
**/
depthjs.OrthoFaceContainer = function()
{
	"use strict";
	
	this.Container_constructor(); // extends createjs.Container
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	
	// this class is designed to simply be the faces for the OrthoPrimitive class
	// in affine only transformations the only way to get good lockup between geometry
	// is to render it orthographically. In order to do that it takes a little screwing
	// with the container/child relationship. So a OrthoFace inside a OrthoPrimitive
	// renders orthographically. It also sorts differently. Each face sorts against
	// each other internally, and the whole object sorts externally with the rest
	// of the scene
	
	// Main reason to override this in OrthoFace is to NOT run depth of field on it, since it's OrthoPrimitive
	// container will handle that. This is so different faces in same object don't have different blurs.
	this.render = function(pDirty)
	{
		pDirty = pDirty !== false;
		
		if (!this._dirty && !pDirty)
			return;
		
		this._dirty = false;
		
		this.updateWorld();
		this.rotateCoords();
		this.rotateObject();
		this.renderObject();
	}
	
	this.renderObject = function()
	{
		var metaPoint = this.transform3D.concatenatedCoordinates;
		
		if (metaPoint.z > parent.stage3D.zoom)
			{ this.transformMatrix.scaleX = 0; return; }
		
		this.transformMatrix.tx = metaPoint.x;
		this.transformMatrix.ty = metaPoint.y;
	}
}

createjs.extend(depthjs.OrthoFaceContainer, createjs.Container);
depthjs.OrthoFaceContainer = createjs.promote(depthjs.OrthoFaceContainer, "Container");

///////////////////////////////////////////////////////////////////////////////////////////////////

/**
The {@link Shape3D} equivalent for usage inside the {@link OrthoPrimitive} class. See those two classes.
@class OrthoFaceShape
@extends createjs.Container
@extends DisplayObject3D
**/
depthjs.OrthoFaceShape = function()
{
	"use strict";
	
	this.Shape_constructor(); // extends createjs.Shape
	depthjs.DisplayObject3D.call(this); // extends depthjs.DisplayObject3D
	
	// this class is designed to simply be the faces for the OrthoPrimitive class
	// in affine only transformations the only way to get good lockup between geometry
	// is to render it orthographically. In order to do that it takes a little screwing
	// with the container/child relationship. So a OrthoFace inside a OrthoPrimitive
	// renders orthographically. It also sorts differently. Each face sorts against
	// each other internally, and the whole object sorts externally with the rest
	// of the scene
	
	// Main reason to override this in OrthoFace is to NOT run depth of field on it, since it's OrthoPrimitive
	// container will handle that. This is so different faces in same object don't have different blurs.
	this.render = function(pDirty)
	{
		pDirty = pDirty !== false;
		
		if (!this._dirty && !pDirty)
			return;
		
		this._dirty = false;
		
		this.updateWorld();
		this.rotateCoords();
		this.rotateObject();
		this.renderObject();
	}
	
	this.renderObject = function()
	{
		var metaPoint = this.transform3D.concatenatedCoordinates;
		
		if (metaPoint.z > parent.stage3D.zoom)
			{ this.transformMatrix.scaleX = 0; return; }
		
		this.transformMatrix.tx = metaPoint.x;
		this.transformMatrix.ty = metaPoint.y;
	}
}

createjs.extend(depthjs.OrthoFaceShape, createjs.Shape);
depthjs.OrthoFaceShape = createjs.promote(depthjs.OrthoFaceShape, "Shape");

///////////////////////////////////////////////////////////////////////////////////////////

/**
Depth of field is an effect by which objects appear blurrier the further they are from the focus of a camera. The DepthOfField class can mimic this effect in DepthJS. To do so set the [Stage3D's depthOfField]{@link Stage3D#depthOfField} property to a DepthOfField instance. NOTE: Blurriness in CreateJS is not the best nor easy on the system. Consider using the {@link AlphaDepthOfField} class instead.
@class DepthOfField
@arg [strength=100] {Number} - Shortcut to the strength property.
@arg [quality=1] {Number} - Shortcut to the quality property.
@arg [trueDistance=true] {Boolean} - Shortcut to the trueDistance property.
**/
depthjs.DepthOfField = function(strength, quality, trueDistance)
{
	"use strict";
	
	/**
	Sets the strength of the effect.
	@var DepthOfField#strength {Number}
	@default 100
	**/
	this.strength = strength || 100;
	/**
	Sets the quality of the effect.
	@var DepthOfField#quality {Number}
	@default 1
	**/
	this.quality = quality || 1;
	/**
	Sets whether the effect utilizes true distance from 0,0,0 (true) or simply the object's z location (false) for the effect.
	@var DepthOfField#trueDistance {Boolean}
	@default true
	**/
	this.trueDistance = trueDistance !== false;
	
	this.render = function(obj, blurObj, filtArr)
	{
		var coords = obj.transform3D.concatenatedCoordinates;
		var x = coords.x, y = coords.y, z = coords.z;
		
		var dist = this.trueDistance ? Math.sqrt( x*x + y*y + z*z ) : Math.abs( z );
		var blurAmt = (this.strength * (dist/obj.stage3D.zoom));
		if (blurAmt == blurObj.blurX) return; // save  some processor if nothin changed
		
		if (blurObj.quality != this.quality) blurObj.quality = this.quality;
		blurObj.blurX = blurObj.blurY = blurAmt;
		obj.filters = filtArr;
		
		var bounds = blurObj.getBounds();
		if (bounds) obj.cache(-50+bounds.x, -50+bounds.y, 100+bounds.width, 100+bounds.height);
	}
}

//////////////////////////////////////////////////////////////////////////////////////////

/**
Depth of field is an effect by which objects appear blurrier the further they are from the focus of a camera. The AlphaDepthOfField class can mimic this effect in DepthJS but with alpha instead of blur. To do so set the [Stage3D's alphDepthOfField]{@link Stage3D#alphaDepthOfField} property to an AlphaDepthOfField instance.
@class AlphaDepthOfField
@arg [strength=100] {Number} - Shortcut to the strength property.
@arg [trueDistance=true] {Boolean} - Shortcut to the trueDistance property.
**/
depthjs.AlphaDepthOfField = function(strength, trueDistance)
{
	"use strict";
	
	/**
	Sets the strength of the effect.
	@var AlphaDepthOfField#strength {Number}
	@default 100
	**/
	this.strength = strength || 100;
	/**
	Sets whether the effect utilizes true distance from 0,0,0 (true) or simply the object's z location (false) for the effect.
	@var AlphaDepthOfField#trueDistance {Boolean}
	@default true
	**/
	this.trueDistance = trueDistance !== false;
	
	this.render = function(obj)
	{
		var coords = obj.transform3D.concatenatedCoordinates;
		var x = coords.x, y = coords.y, z = coords.z;
		var dist = this.trueDistance ? Math.sqrt( x*x + y*y + z*z ) : Math.abs( z );
		
		var alphaToSet = 1.2 - (this.strength * (dist/obj.stage3D.zoom) * .05); // TODO: play with this last number (the .05) to get to where it makes a pretty standard effect with default settings
		
		if (alphaToSet > 1) alphaToSet = 1; if (alphaToSet < 0) alphaToSet = 0;
		
		obj.alpha = alphaToSet;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////

/**
use_namespace allows for a shortcut to namespaces such as depthjs or createjs. By invoking the use_namespace function you can tell which classes you want your project to use as global very simply.
<br><br>
Example: <code>use_namespace('depthjs.Shape3D');</code> would allow you to instantiate the Shape3D class via just <code>new Shape3D()</code> instead of <code>new depthjs.Shape3D();</code>. It can also take the * wildcard. So simply calling <code>use_namespace('depthjs.*');</code> means all DepthJS classes will be accessible without writing out the namespace. The same can be done for <code>use_namespace('createjs.*');</code>
<br><br>
See [this article]{@link http://mbmedia.cc/stuff/use_namespace} for more usage information on use_namespace
@function use_namespace
@see {@link http://mbmedia.cc/stuff/use_namespace}
@arg namePath {String} - The namespace to use, such as "depthjs.Stage3D" or "createjs.*"
@arg [nickName] {String} - In case of conlict you can assign an alternate name to the non-namespaced global classname.
**/
// Free under MIT License | for info: http://mbmedia.cc/stuff/use_namespace
function use_namespace(ns,cl,g)
{
	"use strict";
	g = g || window;
	var a = ns.split('.');
	if (a.length == 1) return;
	var l = cl || a[a.length-1];
	var m = a.pop();
	var b = g[a.shift()];
	while(a.length>0)
		b = b[a.shift()];
	if (l !== '*')
		g[l] = b[m];
	else {
		for (var c in b)
			g[c] = b[c];
	}
}

////////////////////////////////////////////////////////////////////////////////////////////