Explorar el Código

Merge remote branch 'origin/dev' into documentation

OpenShift guest hace 12 años
padre
commit
fe2d302a71

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 365 - 257
build/three.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 433 - 432
build/three.min.js


+ 0 - 5
docs/api/core/BufferGeometry.html

@@ -41,11 +41,6 @@
 		When set, it holds certain buffers in memory to have faster updates for this object. When unset, it deletes those buffers and saves memory.
 		</div>
 		
-		<h3>.[page:Array offsets]</h3>
-		<div>
-		This Array should contain every offset at which the buffers should be rendered. This is important for indexed buffers.
-		</div>
-		
 		<h3>.[page:Array offsets]</h3>
 		<div>
 		This Array should contain every offset at which the buffers should be rendered. This is important for indexed buffers.

+ 23 - 1
src/Three.js

@@ -3,7 +3,7 @@
  * @author Larry Battle / http://bateru.com/news
  */
 
-var THREE = THREE || { REVISION: '55' };
+var THREE = THREE || { REVISION: '56dev' };
 
 self.console = self.console || {
 
@@ -45,6 +45,28 @@ String.prototype.trim = String.prototype.trim || function () {
 
 };
 
+// based on http://stackoverflow.com/a/12317051
+THREE.extend = function ( target, other ) {
+
+	target = target || {};
+
+	for (var prop in other) {
+
+		if ( typeof other[prop] === 'object' ) {
+
+			target[prop] = THREE.extend( target[prop], other[prop] );
+
+		} else {
+
+			target[prop] = other[prop];
+
+		}
+
+	}
+
+	return target;
+
+};
 
 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

+ 1 - 1
src/core/Projector.js

@@ -4,7 +4,7 @@
  * @author julianwa / https://github.com/julianwa
  */
 
-THREE.Projector = function() {
+THREE.Projector = function () {
 
 	var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
 	_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,

+ 1 - 1
src/core/Raycaster.js

@@ -8,7 +8,7 @@
 	THREE.Raycaster = function ( origin, direction, near, far ) {
 
 		this.ray = new THREE.Ray( origin, direction );
-		
+
 		// normalized ray.direction required for accurate distance calculations
 		if( this.ray.direction.length() > 0 ) {
 

+ 1 - 1
src/extras/core/Shape.js

@@ -9,7 +9,7 @@
 // STEP 3a - Extract points from each shape, turn to vertices
 // STEP 3b - Triangulate each shape, add faces.
 
-THREE.Shape = function ( ) {
+THREE.Shape = function () {
 
 	THREE.Path.apply( this, arguments );
 	this.holes = [];

+ 1 - 1
src/extras/objects/ImmediateRenderObject.js

@@ -2,7 +2,7 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.ImmediateRenderObject = function ( ) {
+THREE.ImmediateRenderObject = function () {
 
 	THREE.Object3D.call( this );
 

+ 1 - 1
src/extras/renderers/plugins/DepthPassPlugin.js

@@ -2,7 +2,7 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.DepthPassPlugin = function ( ) {
+THREE.DepthPassPlugin = function () {
 
 	this.enabled = false;
 	this.renderTarget = null;

+ 1 - 1
src/extras/renderers/plugins/LensFlarePlugin.js

@@ -3,7 +3,7 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.LensFlarePlugin = function ( ) {
+THREE.LensFlarePlugin = function () {
 
 	var _gl, _renderer, _precision, _lensFlare = {};
 

+ 1 - 1
src/extras/renderers/plugins/ShadowMapPlugin.js

@@ -2,7 +2,7 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.ShadowMapPlugin = function ( ) {
+THREE.ShadowMapPlugin = function () {
 
 	var _gl,
 	_renderer,

+ 1 - 1
src/extras/renderers/plugins/SpritePlugin.js

@@ -3,7 +3,7 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.SpritePlugin = function ( ) {
+THREE.SpritePlugin = function () {
 
 	var _gl, _renderer, _precision, _sprite = {};
 

+ 24 - 16
src/math/Box2.js

@@ -9,9 +9,7 @@ THREE.Box2 = function ( min, max ) {
 
 };
 
-THREE.Box2.prototype = {
-
-	constructor: THREE.Box2,
+THREE.extend( THREE.Box2.prototype, {
 
 	set: function ( min, max ) {
 
@@ -67,15 +65,21 @@ THREE.Box2.prototype = {
 
 	},
 
-	setFromCenterAndSize: function ( center, size ) {
+	setFromCenterAndSize: function() {
 
-		var halfSize = THREE.Box2.__v1.copy( size ).multiplyScalar( 0.5 );
-		this.min.copy( center ).sub( halfSize );
-		this.max.copy( center ).add( halfSize );
+		var v1 = new THREE.Vector2();
 
-		return this;
+		return function ( center, size ) {
 
-	},
+			var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
+			this.min.copy( center ).sub( halfSize );
+			this.max.copy( center ).add( halfSize );
+
+			return this;
+
+		};
+
+	}(),
 
 	copy: function ( box ) {
 
@@ -201,12 +205,18 @@ THREE.Box2.prototype = {
 
 	},
 
-	distanceToPoint: function ( point ) {
+	distanceToPoint: function() {
 
-		var clampedPoint = THREE.Box2.__v1.copy( point ).clamp( this.min, this.max );
-		return clampedPoint.sub( point ).length();
+		var v1 = new THREE.Vector2();
 
-	},
+		return function ( point ) {
+
+			var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
+			return clampedPoint.sub( point ).length();
+
+		};
+
+	}(),
 
 	intersect: function ( box ) {
 
@@ -247,6 +257,4 @@ THREE.Box2.prototype = {
 
 	}
 
-};
-
-THREE.Box2.__v1 = new THREE.Vector2();
+} );

+ 66 - 47
src/math/Box3.js

@@ -9,9 +9,7 @@ THREE.Box3 = function ( min, max ) {
 
 };
 
-THREE.Box3.prototype = {
-
-	constructor: THREE.Box3,
+THREE.extend( THREE.Box3.prototype, {
 
 	set: function ( min, max ) {
 
@@ -77,16 +75,22 @@ THREE.Box3.prototype = {
 
 	},
 
-	setFromCenterAndSize: function ( center, size ) {
+	setFromCenterAndSize: function() {
 
-		var halfSize = THREE.Box3.__v1.copy( size ).multiplyScalar( 0.5 );
+		var v1 = new THREE.Vector3();
 
-		this.min.copy( center ).sub( halfSize );
-		this.max.copy( center ).add( halfSize );
+		return function ( center, size ) {
 
-		return this;
+			var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
 
-	},
+			this.min.copy( center ).sub( halfSize );
+			this.max.copy( center ).add( halfSize );
+
+			return this;
+
+		};
+
+	}(),
 
 	copy: function ( box ) {
 
@@ -215,27 +219,39 @@ THREE.Box3.prototype = {
 	clampPoint: function ( point, optionalTarget ) {
 
 		var result = optionalTarget || new THREE.Vector3();
-		return new THREE.Vector3().copy( point ).clamp( this.min, this.max );
+		return result.copy( point ).clamp( this.min, this.max );
 
 	},
 
-	distanceToPoint: function ( point ) {
+	distanceToPoint: function() {
 
-		var clampedPoint = THREE.Box3.__v1.copy( point ).clamp( this.min, this.max );
-		return clampedPoint.sub( point ).length();
+		var v1 = new THREE.Vector3();
 
-	},
+		return function ( point ) {
 
-	getBoundingSphere: function ( optionalTarget ) {
+			var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
+			return clampedPoint.sub( point ).length();
 
-		var result = optionalTarget || new THREE.Sphere();
+		};
 
-		result.center = this.center();
-		result.radius = this.size( THREE.Box3.__v0 ).length() * 0.5;
+	}(),
 
-		return result;
+	getBoundingSphere: function() {
 
-	},
+		var v1 = new THREE.Vector3();
+
+		return function ( optionalTarget ) {
+
+			var result = optionalTarget || new THREE.Sphere();
+
+			result.center = this.center();
+			result.radius = this.size( v1 ).length() * 0.5;
+
+			return result;
+
+		};
+
+	}(),
 
 	intersect: function ( box ) {
 
@@ -255,27 +271,39 @@ THREE.Box3.prototype = {
 
 	},
 
-	transform: function ( matrix ) {
+	transform: function() {
+
+		var points = [
+			new THREE.Vector3(),
+			new THREE.Vector3(),
+			new THREE.Vector3(),
+			new THREE.Vector3(),
+			new THREE.Vector3(),
+			new THREE.Vector3(),
+			new THREE.Vector3(),
+			new THREE.Vector3()
+			];
+
+		return function ( matrix ) {
+
+			// NOTE: I am using a binary pattern to specify all 2^3 combinations below
+			points[0].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000
+			points[1].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001
+			points[2].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010
+			points[3].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011
+			points[4].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100
+			points[5].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101
+			points[6].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110
+			points[7].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );  // 111
 
-		// NOTE: I am using a binary pattern to specify all 2^3 combinations below
-		var newPoints = [
-			THREE.Box3.__v0.set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ),
-			THREE.Box3.__v0.set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ), // 000
-			THREE.Box3.__v1.set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ), // 001
-			THREE.Box3.__v2.set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ), // 010
-			THREE.Box3.__v3.set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ), // 011
-			THREE.Box3.__v4.set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ), // 100
-			THREE.Box3.__v5.set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ), // 101
-			THREE.Box3.__v6.set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ), // 110
-			THREE.Box3.__v7.set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix )  // 111
-		];
+			this.makeEmpty();
+			this.setFromPoints( points );
 
-		this.makeEmpty();
-		this.setFromPoints( newPoints );
+			return this;
 
-		return this;
+		};
 
-	},
+	}(),
 
 	translate: function ( offset ) {
 
@@ -298,13 +326,4 @@ THREE.Box3.prototype = {
 
 	}
 
-};
-
-THREE.Box3.__v0 = new THREE.Vector3();
-THREE.Box3.__v1 = new THREE.Vector3();
-THREE.Box3.__v2 = new THREE.Vector3();
-THREE.Box3.__v3 = new THREE.Vector3();
-THREE.Box3.__v4 = new THREE.Vector3();
-THREE.Box3.__v5 = new THREE.Vector3();
-THREE.Box3.__v6 = new THREE.Vector3();
-THREE.Box3.__v7 = new THREE.Vector3();
+} );

+ 2 - 5
src/math/Color.js

@@ -10,13 +10,10 @@ THREE.Color = function ( value ) {
 
 };
 
-THREE.Color.prototype = {
-
-	constructor: THREE.Color,
+THREE.extend( THREE.Color.prototype, {
 
 	r: 1, g: 1, b: 1,
 
-
 	set: function ( value ) {
 
 		switch ( typeof value ) {
@@ -390,7 +387,7 @@ THREE.Color.prototype = {
 
 	}
 
-};
+} );
 
 THREE.ColorKeywords = { "aliceblue": 0xF0F8FF, "antiquewhite": 0xFAEBD7, "aqua": 0x00FFFF, "aquamarine": 0x7FFFD4, "azure": 0xF0FFFF,
 "beige": 0xF5F5DC, "bisque": 0xFFE4C4, "black": 0x000000, "blanchedalmond": 0xFFEBCD, "blue": 0x0000FF, "blueviolet": 0x8A2BE2,

+ 2 - 2
src/math/Frustum.js

@@ -19,7 +19,7 @@ THREE.Frustum = function ( p0, p1, p2, p3, p4, p5 ) {
 
 };
 
-THREE.Frustum.prototype = {
+THREE.extend( THREE.Frustum.prototype, {
 
 	set: function ( p0, p1, p2, p3, p4, p5 ) {
 
@@ -140,4 +140,4 @@ THREE.Frustum.prototype = {
 
 	}
 
-};
+} );

+ 18 - 9
src/math/Math.js

@@ -67,19 +67,28 @@ THREE.Math = {
 
 	},
 
-	degToRad: function ( degrees ) {
+	degToRad: function() {
 
-		return degrees * THREE.Math.__d2r;
+		var degreeToRadiansFactor = Math.PI / 180;
 
-	},
+		return function ( degrees ) {
 
-	radToDeg: function ( radians ) {
+			return degrees * degreeToRadiansFactor;
 
-		return radians * THREE.Math.__r2d;
+		};
 
-	}
+	}(),
 
-};
+	radToDeg: function() {
+
+		var radianToDegreesFactor = 180 / Math.PI;
+
+		return function ( radians ) {
 
-THREE.Math.__d2r =  Math.PI / 180;
-THREE.Math.__r2d =  180 / Math.PI;
+			return radians * radianToDegreesFactor;
+
+		};
+
+	}()
+
+};

+ 28 - 20
src/math/Matrix3.js

@@ -17,9 +17,7 @@ THREE.Matrix3 = function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
 	);
 };
 
-THREE.Matrix3.prototype = {
-
-	constructor: THREE.Matrix3,
+THREE.extend( THREE.Matrix3.prototype, {
 
 	set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
 
@@ -70,27 +68,31 @@ THREE.Matrix3.prototype = {
 
 	},
 
-	multiplyVector3Array: function ( a ) {
+	multiplyVector3Array: function() {
 
-		var tmp = THREE.Matrix3.__v1;
+		var v1 = new THREE.Vector3();
 
-		for ( var i = 0, il = a.length; i < il; i += 3 ) {
+		return function ( a ) {
 
-			tmp.x = a[ i ];
-			tmp.y = a[ i + 1 ];
-			tmp.z = a[ i + 2 ];
+			for ( var i = 0, il = a.length; i < il; i += 3 ) {
 
-			tmp.applyMatrix3(this);
+				v1.x = a[ i ];
+				v1.y = a[ i + 1 ];
+				v1.z = a[ i + 2 ];
 
-			a[ i ]     = tmp.x;
-			a[ i + 1 ] = tmp.y;
-			a[ i + 2 ] = tmp.z;
+				v1.applyMatrix3(this);
 
-		}
+				a[ i ]     = v1.x;
+				a[ i + 1 ] = v1.y;
+				a[ i + 2 ] = v1.z;
 
-		return a;
+			}
 
-	},
+			return a;
+
+		};
+
+	}(),
 
 	multiplyScalar: function ( s ) {
 
@@ -164,7 +166,6 @@ THREE.Matrix3.prototype = {
 
 	},
 
-
 	transpose: function () {
 
 		var tmp, m = this.elements;
@@ -177,6 +178,15 @@ THREE.Matrix3.prototype = {
 
 	},
 
+	getNormalMatrix: function ( m ) {
+
+		// input: THREE.Matrix4
+
+		this.getInverse( m ).transpose();
+
+		return this;
+
+	},
 
 	transposeIntoArray: function ( r ) {
 
@@ -210,6 +220,4 @@ THREE.Matrix3.prototype = {
 
 	}
 
-};
-
-THREE.Matrix3.__v1 = new THREE.Vector3();
+} );

+ 164 - 134
src/math/Matrix4.js

@@ -13,22 +13,19 @@
 
 THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
 
-	this.elements = new Float32Array( 16 );
+	var te = this.elements = new Float32Array( 16 );
 
-	this.set(
+	// TODO: if n11 is undefined, then just set to identity, otherwise copy all other values into matrix
+	//   we should not support semi specification of Matrix4, it is just weird.
 
-		( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
-		n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
-		n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
-		n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
-
-	);
+	te[0] = ( n11 !== undefined ) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0;
+	te[1] = n21 || 0; te[5] = ( n22 !== undefined ) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0;
+	te[2] = n31 || 0; te[6] = n32 || 0; te[10] = ( n33 !== undefined ) ? n33 : 1; te[14] = n34 || 0;
+	te[3] = n41 || 0; te[7] = n42 || 0; te[11] = n43 || 0; te[15] = ( n44 !== undefined ) ? n44 : 1;
 
 };
 
-THREE.Matrix4.prototype = {
-
-	constructor: THREE.Matrix4,
+THREE.extend( THREE.Matrix4.prototype, {
 
 	set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
 
@@ -212,41 +209,45 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	lookAt: function ( eye, target, up ) {
-
-		var te = this.elements;
+	lookAt: function() {
 
-		var x = THREE.Matrix4.__v1;
-		var y = THREE.Matrix4.__v2;
-		var z = THREE.Matrix4.__v3;
+		var x = new THREE.Vector3();
+		var y = new THREE.Vector3();
+		var z = new THREE.Vector3();
 
-		z.subVectors( eye, target ).normalize();
+		return function ( eye, target, up ) {
 
-		if ( z.length() === 0 ) {
+			var te = this.elements;
 
-			z.z = 1;
+			z.subVectors( eye, target ).normalize();
 
-		}
+			if ( z.length() === 0 ) {
 
-		x.crossVectors( up, z ).normalize();
+				z.z = 1;
 
-		if ( x.length() === 0 ) {
+			}
 
-			z.x += 0.0001;
 			x.crossVectors( up, z ).normalize();
 
-		}
+			if ( x.length() === 0 ) {
 
-		y.crossVectors( z, x );
+				z.x += 0.0001;
+				x.crossVectors( up, z ).normalize();
 
+			}
 
-		te[0] = x.x; te[4] = y.x; te[8] = z.x;
-		te[1] = x.y; te[5] = y.y; te[9] = z.y;
-		te[2] = x.z; te[6] = y.z; te[10] = z.z;
+			y.crossVectors( z, x );
 
-		return this;
 
-	},
+			te[0] = x.x; te[4] = y.x; te[8] = z.x;
+			te[1] = x.y; te[5] = y.y; te[9] = z.y;
+			te[2] = x.z; te[6] = y.z; te[10] = z.z;
+
+			return this;
+
+		};
+
+	}(),
 
 	multiply: function ( m, n ) {
 
@@ -343,27 +344,31 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	multiplyVector3Array: function ( a ) {
+	multiplyVector3Array: function() {
 
-		var tmp = THREE.Matrix4.__v1;
+		var v1 = new THREE.Vector3();
 
-		for ( var i = 0, il = a.length; i < il; i += 3 ) {
+		return function ( a ) {
 
-			tmp.x = a[ i ];
-			tmp.y = a[ i + 1 ];
-			tmp.z = a[ i + 2 ];
+			for ( var i = 0, il = a.length; i < il; i += 3 ) {
 
-			tmp.applyProjection( this );
+				v1.x = a[ i ];
+				v1.y = a[ i + 1 ];
+				v1.z = a[ i + 2 ];
 
-			a[ i ]     = tmp.x;
-			a[ i + 1 ] = tmp.y;
-			a[ i + 2 ] = tmp.z;
+				v1.applyProjection( this );
 
-		}
+				a[ i ]     = v1.x;
+				a[ i + 1 ] = v1.y;
+				a[ i + 2 ] = v1.z;
 
-		return a;
+			}
 
-	},
+			return a;
+
+		};
+
+	}(),
 
 	rotateAxis: function ( v ) {
 
@@ -501,12 +506,18 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	getPosition: function () {
+	getPosition: function() {
 
-		var te = this.elements;
-		return THREE.Matrix4.__v1.set( te[12], te[13], te[14] );
+		var v1 = new THREE.Vector3();
 
-	},
+		return function () {
+
+			var te = this.elements;
+			return v1.set( te[12], te[13], te[14] );
+
+		};
+
+	}(),
 
 	setPosition: function ( v ) {
 
@@ -520,26 +531,44 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	getColumnX: function () {
+	getColumnX: function() {
 
-		var te = this.elements;
-		return THREE.Matrix4.__v1.set( te[0], te[1], te[2] );
+		var v1 = new THREE.Vector3();
 
-	},
+		return function () {
 
-	getColumnY: function () {
+			var te = this.elements;
+			return v1.set( te[0], te[1], te[2] );
 
-		var te = this.elements;
-		return THREE.Matrix4.__v1.set( te[4], te[5], te[6] );
+		};
 
-	},
+	}(),
+
+	getColumnY: function() {
+
+		var v1 = new THREE.Vector3();
+
+		return function () {
+
+			var te = this.elements;
+			return v1.set( te[4], te[5], te[6] );
+
+		};
+
+	}(),
 
 	getColumnZ: function() {
 
-		var te = this.elements;
-		return THREE.Matrix4.__v1.set( te[8], te[9], te[10] );
+		var v1 = new THREE.Vector3();
 
-	},
+		return function() {
+
+			var te = this.elements;
+			return v1.set( te[8], te[9], te[10] );
+
+		};
+
+	}(),
 
 	getInverse: function ( m, throwOnInvertible ) {
 
@@ -596,75 +625,83 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	compose: function ( translation, rotation, scale ) {
+	compose: function() {
 
-		var te = this.elements;
-		var mRotation = THREE.Matrix4.__m1;
-		var mScale = THREE.Matrix4.__m2;
+		var mRotation = new THREE.Matrix4(),
+			mScale = new THREE.Matrix4();
+		
+		return function ( translation, rotation, scale ) {
 
-		mRotation.identity();
-		mRotation.setRotationFromQuaternion( rotation );
+			var te = this.elements;
 
-		mScale.makeScale( scale.x, scale.y, scale.z );
+			mRotation.identity();
+			mRotation.setRotationFromQuaternion( rotation );
 
-		this.multiplyMatrices( mRotation, mScale );
+			mScale.makeScale( scale.x, scale.y, scale.z );
 
-		te[12] = translation.x;
-		te[13] = translation.y;
-		te[14] = translation.z;
+			this.multiplyMatrices( mRotation, mScale );
 
-		return this;
+			te[12] = translation.x;
+			te[13] = translation.y;
+			te[14] = translation.z;
 
-	},
+			return this;
 
-	decompose: function ( translation, rotation, scale ) {
+		};
 
-		var te = this.elements;
+	}(),
 
-		// grab the axis vectors
-		var x = THREE.Matrix4.__v1;
-		var y = THREE.Matrix4.__v2;
-		var z = THREE.Matrix4.__v3;
+	decompose: function() {
 
-		x.set( te[0], te[1], te[2] );
-		y.set( te[4], te[5], te[6] );
-		z.set( te[8], te[9], te[10] );
+		var x = new THREE.Vector3(),
+			y = new THREE.Vector3(),
+			z = new THREE.Vector3(),
+			matrix = new THREE.Matrix4();
 
-		translation = ( translation instanceof THREE.Vector3 ) ? translation : new THREE.Vector3();
-		rotation = ( rotation instanceof THREE.Quaternion ) ? rotation : new THREE.Quaternion();
-		scale = ( scale instanceof THREE.Vector3 ) ? scale : new THREE.Vector3();
+		return function ( translation, rotation, scale ) {
 
-		scale.x = x.length();
-		scale.y = y.length();
-		scale.z = z.length();
+			var te = this.elements;
 
-		translation.x = te[12];
-		translation.y = te[13];
-		translation.z = te[14];
+			// grab the axis vectors
+			x.set( te[0], te[1], te[2] );
+			y.set( te[4], te[5], te[6] );
+			z.set( te[8], te[9], te[10] );
 
-		// scale the rotation part
+			translation = ( translation instanceof THREE.Vector3 ) ? translation : new THREE.Vector3();
+			rotation = ( rotation instanceof THREE.Quaternion ) ? rotation : new THREE.Quaternion();
+			scale = ( scale instanceof THREE.Vector3 ) ? scale : new THREE.Vector3();
 
-		var matrix = THREE.Matrix4.__m1;
+			scale.x = x.length();
+			scale.y = y.length();
+			scale.z = z.length();
 
-		matrix.copy( this );
+			translation.x = te[12];
+			translation.y = te[13];
+			translation.z = te[14];
 
-		matrix.elements[0] /= scale.x;
-		matrix.elements[1] /= scale.x;
-		matrix.elements[2] /= scale.x;
+			// scale the rotation part
 
-		matrix.elements[4] /= scale.y;
-		matrix.elements[5] /= scale.y;
-		matrix.elements[6] /= scale.y;
+			matrix.copy( this );
 
-		matrix.elements[8] /= scale.z;
-		matrix.elements[9] /= scale.z;
-		matrix.elements[10] /= scale.z;
+			matrix.elements[0] /= scale.x;
+			matrix.elements[1] /= scale.x;
+			matrix.elements[2] /= scale.x;
 
-		rotation.setFromRotationMatrix( matrix );
+			matrix.elements[4] /= scale.y;
+			matrix.elements[5] /= scale.y;
+			matrix.elements[6] /= scale.y;
 
-		return [ translation, rotation, scale ];
+			matrix.elements[8] /= scale.z;
+			matrix.elements[9] /= scale.z;
+			matrix.elements[10] /= scale.z;
 
-	},
+			rotation.setFromRotationMatrix( matrix );
+
+			return [ translation, rotation, scale ];
+
+		};
+
+	}(),
 
 	extractPosition: function ( m ) {
 
@@ -679,34 +716,36 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	extractRotation: function ( m ) {
+	extractRotation: function() {
 
-		var te = this.elements;
-		var me = m.elements;
+		var v1 = new THREE.Vector3();
 
-		var vector = THREE.Matrix4.__v1;
+		return function ( m ) {
 
-		var scaleX = 1 / vector.set( me[0], me[1], me[2] ).length();
-		var scaleY = 1 / vector.set( me[4], me[5], me[6] ).length();
-		var scaleZ = 1 / vector.set( me[8], me[9], me[10] ).length();
+			var te = this.elements;
+			var me = m.elements;
 
-		te[0] = me[0] * scaleX;
-		te[1] = me[1] * scaleX;
-		te[2] = me[2] * scaleX;
+			var scaleX = 1 / v1.set( me[0], me[1], me[2] ).length();
+			var scaleY = 1 / v1.set( me[4], me[5], me[6] ).length();
+			var scaleZ = 1 / v1.set( me[8], me[9], me[10] ).length();
 
-		te[4] = me[4] * scaleY;
-		te[5] = me[5] * scaleY;
-		te[6] = me[6] * scaleY;
+			te[0] = me[0] * scaleX;
+			te[1] = me[1] * scaleX;
+			te[2] = me[2] * scaleX;
 
-		te[8] = me[8] * scaleZ;
-		te[9] = me[9] * scaleZ;
-		te[10] = me[10] * scaleZ;
+			te[4] = me[4] * scaleY;
+			te[5] = me[5] * scaleY;
+			te[6] = me[6] * scaleY;
 
-		return this;
+			te[8] = me[8] * scaleZ;
+			te[9] = me[9] * scaleZ;
+			te[10] = me[10] * scaleZ;
 
-	},
+			return this;
 
-	//
+		};
+
+	}(),
 
 	translate: function ( v ) {
 
@@ -904,8 +943,6 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	//
-
 	makeTranslation: function ( x, y, z ) {
 
 		this.set(
@@ -1076,11 +1113,4 @@ THREE.Matrix4.prototype = {
 
 	}
 
-};
-
-THREE.Matrix4.__v1 = new THREE.Vector3();
-THREE.Matrix4.__v2 = new THREE.Vector3();
-THREE.Matrix4.__v3 = new THREE.Vector3();
-
-THREE.Matrix4.__m1 = new THREE.Matrix4();
-THREE.Matrix4.__m2 = new THREE.Matrix4();
+} );

+ 57 - 41
src/math/Plane.js

@@ -9,9 +9,7 @@ THREE.Plane = function ( normal, constant ) {
 
 };
 
-THREE.Plane.prototype = {
-
-	constructor: THREE.Plane,
+THREE.extend( THREE.Plane.prototype, {
 
 	set: function ( normal, constant ) {
 
@@ -40,17 +38,25 @@ THREE.Plane.prototype = {
 
 	},
 
-	setFromCoplanarPoints: function ( a, b, c ) {
+	setFromCoplanarPoints: function() {
 
-		var normal = THREE.Plane.__v1.subVectors( c, b ).cross( THREE.Plane.__v2.subVectors( a, b ) ).normalize();
+		var v1 = new THREE.Vector3();
+		var v2 = new THREE.Vector3();
 
-		// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
+		return function ( a, b, c ) {
 
-		this.setFromNormalAndCoplanarPoint( normal, a );
+			var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
 
-		return this;
+			// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
+
+			this.setFromNormalAndCoplanarPoint( normal, a );
+
+			return this;
+
+		};
+
+	}(),
 
-	},
 
 	copy: function ( plane ) {
 
@@ -120,39 +126,46 @@ THREE.Plane.prototype = {
 
 	},
 
-	intersectLine: function ( startPoint, endPoint, optionalTarget ) {
+	intersectLine: function() {
 
-		var result = optionalTarget || new THREE.Vector3();
+		var v1 = new THREE.Vector3();
+
+		return function ( startPoint, endPoint, optionalTarget ) {
+
+			var result = optionalTarget || new THREE.Vector3();
+
+			var direction = v1.subVectors( endPoint, startPoint );
 
-		var direction = THREE.Plane.__v1.subVectors( endPoint, startPoint );
+			var denominator = this.normal.dot( direction );
 
-		var denominator = this.normal.dot( direction );
+			if ( denominator == 0 ) {
 
-		if ( denominator == 0 ) {
+				// line is coplanar, return origin
+				if( this.distanceToPoint( startPoint ) == 0 ) {
 
-			// line is coplanar, return origin
-			if( this.distanceToPoint( startPoint ) == 0 ) {
+					return result.copy( startPoint );
 
-				return result.copy( startPoint );
+				}
+
+				// Unsure if this is the correct method to handle this case.
+				return undefined;
 
 			}
 
-			// Unsure if this is the correct method to handle this case.
-			return undefined;
+			var t = - ( startPoint.dot( this.normal ) + this.constant ) / denominator;
 
-		}
+			if( t < 0 || t > 1 ) {
 
-		var t = - ( startPoint.dot( this.normal ) + this.constant ) / denominator;
+				return undefined;
 
-		if( t < 0 || t > 1 ) {
+			}
 
-			return undefined;
+			return result.copy( direction ).multiplyScalar( t ).add( startPoint );
 
-		}
+		};
 
-		return result.copy( direction ).multiplyScalar( t ).add( startPoint );
+	}(),
 
-	},
 
 	coplanarPoint: function ( optionalTarget ) {
 
@@ -161,21 +174,28 @@ THREE.Plane.prototype = {
 
 	},
 
-	transform: function ( matrix, optionalNormalMatrix ) {
+	transform: function() {
 
-		// compute new normal based on theory here:
-		// http://www.songho.ca/opengl/gl_normaltransform.html
-		optionalNormalMatrix = optionalNormalMatrix || new THREE.Matrix3().getInverse( matrix ).transpose();
-		var newNormal = THREE.Plane.__v1.copy( this.normal ).applyMatrix3( optionalNormalMatrix );
+		var v1 = new THREE.Vector3();
+		var v2 = new THREE.Vector3();
 
-		var newCoplanarPoint = this.coplanarPoint( THREE.Plane.__v2 );
-		newCoplanarPoint.applyMatrix4( matrix );
+		return function ( matrix, optionalNormalMatrix ) {
 
-		this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
+			// compute new normal based on theory here:
+			// http://www.songho.ca/opengl/gl_normaltransform.html
+			optionalNormalMatrix = optionalNormalMatrix || new THREE.Matrix3().getInverse( matrix ).transpose();
+			var newNormal = v1.copy( this.normal ).applyMatrix3( optionalNormalMatrix );
 
-		return this;
+			var newCoplanarPoint = this.coplanarPoint( v2 );
+			newCoplanarPoint.applyMatrix4( matrix );
 
-	},
+			this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
+
+			return this;
+
+		};
+
+	}(),
 
 	translate: function ( offset ) {
 
@@ -197,8 +217,4 @@ THREE.Plane.prototype = {
 
 	}
 
-};
-
-THREE.Plane.__vZero = new THREE.Vector3( 0, 0, 0 );
-THREE.Plane.__v1 = new THREE.Vector3();
-THREE.Plane.__v2 = new THREE.Vector3();
+} );

+ 2 - 4
src/math/Quaternion.js

@@ -14,9 +14,7 @@ THREE.Quaternion = function( x, y, z, w ) {
 
 };
 
-THREE.Quaternion.prototype = {
-
-	constructor: THREE.Quaternion,
+THREE.extend( THREE.Quaternion.prototype, {
 
 	set: function ( x, y, z, w ) {
 
@@ -339,7 +337,7 @@ THREE.Quaternion.prototype = {
 
 	}
 
-}
+} );
 
 THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
 

+ 24 - 17
src/math/Ray.js

@@ -9,9 +9,7 @@ THREE.Ray = function ( origin, direction ) {
 
 };
 
-THREE.Ray.prototype = {
-
-	constructor: THREE.Ray,
+THREE.extend( THREE.Ray.prototype, {
 
 	set: function ( origin, direction ) {
 
@@ -39,13 +37,19 @@ THREE.Ray.prototype = {
 
 	},
 
-	recast: function ( t ) {
+	recast: function() {
 
-		this.origin.copy( this.at( t, THREE.Ray.__v1 ) );
+		var v1 = new THREE.Vector3();
 
-		return this;
+		return function ( t ) {
 
-	},
+			this.origin.copy( this.at( t, v1 ) );
+
+			return this;
+
+		};
+
+	}(),
 
 	closestPointToPoint: function ( point, optionalTarget ) {
 
@@ -57,14 +61,20 @@ THREE.Ray.prototype = {
 
 	},
 
-	distanceToPoint: function ( point ) {
+	distanceToPoint: function() {
 
-		var directionDistance = THREE.Ray.__v1.subVectors( point, this.origin ).dot( this.direction );
-		THREE.Ray.__v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
+		var v1 = new THREE.Vector3();
 
-		return THREE.Ray.__v1.distanceTo( point );
+		return function ( point ) {
 
-	},
+			var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );
+			v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
+
+			return v1.distanceTo( point );
+
+		};
+
+	}(),
 
 	isIntersectionSphere: function( sphere ) {
 
@@ -121,7 +131,7 @@ THREE.Ray.prototype = {
 
 		var t = this.distanceToPlane( plane );
 
-		if( t === undefined ) {
+		if ( t === undefined ) {
 
 			return undefined;
 		}
@@ -151,7 +161,4 @@ THREE.Ray.prototype = {
 
 	}
 
-};
-
-THREE.Ray.__v1 = new THREE.Vector3();
-THREE.Ray.__v2 = new THREE.Vector3();
+} );

+ 2 - 4
src/math/Sphere.js

@@ -10,9 +10,7 @@ THREE.Sphere = function ( center, radius ) {
 
 };
 
-THREE.Sphere.prototype = {
-
-	constructor: THREE.Sphere,
+THREE.extend( THREE.Sphere.prototype, {
 
 	set: function ( center, radius ) {
 
@@ -133,4 +131,4 @@ THREE.Sphere.prototype = {
 
 	}
 
-};
+} );

+ 72 - 51
src/math/Triangle.js

@@ -11,69 +11,88 @@ THREE.Triangle = function ( a, b, c ) {
 
 };
 
-THREE.Triangle.normal = function( a, b, c, optionalTarget ) {
+THREE.Triangle.normal = function() {
 
-	var result = optionalTarget || new THREE.Vector3();
+	var v0 = new THREE.Vector3();
 
-	result.subVectors( c, b );
-	THREE.Triangle.__v0.subVectors( a, b );
-	result.cross( THREE.Triangle.__v0 );
+	return function( a, b, c, optionalTarget ) {
 
-	var resultLengthSq = result.lengthSq();
-	if( resultLengthSq > 0 ) {
+		var result = optionalTarget || new THREE.Vector3();
 
-		return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
+		result.subVectors( c, b );
+		v0.subVectors( a, b );
+		result.cross( v0 );
 
-	}
+		var resultLengthSq = result.lengthSq();
+		if( resultLengthSq > 0 ) {
 
-	return result.set( 0, 0, 0 );
+			return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
 
-};
+		}
+
+		return result.set( 0, 0, 0 );
+
+	};
+
+}();
 
 // static/instance method to calculate barycoordinates
 // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
-THREE.Triangle.barycoordFromPoint = function ( point, a, b, c, optionalTarget ) {
+THREE.Triangle.barycoordFromPoint = function() {
 
-	THREE.Triangle.__v0.subVectors( c, a );
-	THREE.Triangle.__v1.subVectors( b, a );
-	THREE.Triangle.__v2.subVectors( point, a );
+	var v0 = new THREE.Vector3(),
+		v1 = new THREE.Vector3(),
+		v2 = new THREE.Vector3();
 
-	var dot00 = THREE.Triangle.__v0.dot( THREE.Triangle.__v0 );
-	var dot01 = THREE.Triangle.__v0.dot( THREE.Triangle.__v1 );
-	var dot02 = THREE.Triangle.__v0.dot( THREE.Triangle.__v2 );
-	var dot11 = THREE.Triangle.__v1.dot( THREE.Triangle.__v1 );
-	var dot12 = THREE.Triangle.__v1.dot( THREE.Triangle.__v2 );
+	return function ( point, a, b, c, optionalTarget ) {
 
-	var denom = ( dot00 * dot11 - dot01 * dot01 );
+		v0.subVectors( c, a );
+		v1.subVectors( b, a );
+		v2.subVectors( point, a );
 
-	var result = optionalTarget || new THREE.Vector3();
+		var dot00 = v0.dot( v0 );
+		var dot01 = v0.dot( v1 );
+		var dot02 = v0.dot( v2 );
+		var dot11 = v1.dot( v1 );
+		var dot12 = v1.dot( v2 );
 
-	// colinear or singular triangle
-	if( denom == 0 ) {
-		// arbitrary location outside of triangle?
-		// not sure if this is the best idea, maybe should be returning undefined
-		return result.set( -2, -1, -1 );
-	}
+		var denom = ( dot00 * dot11 - dot01 * dot01 );
 
-	var invDenom = 1 / denom;
-	var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
-	var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
+		var result = optionalTarget || new THREE.Vector3();
 
-	// barycoordinates must always sum to 1
-	return result.set( 1 - u - v, v, u );
+		// colinear or singular triangle
+		if( denom == 0 ) {
+			// arbitrary location outside of triangle?
+			// not sure if this is the best idea, maybe should be returning undefined
+			return result.set( -2, -1, -1 );
+		}
 
-};
+		var invDenom = 1 / denom;
+		var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
+		var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
 
-THREE.Triangle.containsPoint = function ( point, a, b, c ) {
+		// barycoordinates must always sum to 1
+		return result.set( 1 - u - v, v, u );
 
-	// NOTE: need to use __v3 here because __v0, __v1 and __v2 are used in barycoordFromPoint.
-	var result = THREE.Triangle.barycoordFromPoint( point, a, b, c, THREE.Triangle.__v3 );
+	};
 
-	return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
+}();
 
-};
+THREE.Triangle.containsPoint = function() {
+
+	var v1 = new THREE.Vector3();
 
-THREE.Triangle.prototype = {
+	return function ( point, a, b, c ) {
+
+		var result = THREE.Triangle.barycoordFromPoint( point, a, b, c, v1 );
+
+		return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
+
+	};
+
+}();
+
+THREE.extend( THREE.Triangle.prototype, {
 
 	constructor: THREE.Triangle,
 
@@ -107,14 +126,21 @@ THREE.Triangle.prototype = {
 
 	},
 
-	area: function () {
+	area: function() {
 
-		THREE.Triangle.__v0.subVectors( this.c, this.b );
-		THREE.Triangle.__v1.subVectors( this.a, this.b );
+		var v0 = new THREE.Vector3();
+		var v1 = new THREE.Vector3();
 
-		return THREE.Triangle.__v0.cross( THREE.Triangle.__v1 ).length() * 0.5;
+		return function () {
 
-	},
+			v0.subVectors( this.c, this.b );
+			v1.subVectors( this.a, this.b );
+
+			return v0.cross( v1 ).length() * 0.5;
+
+		};
+
+	}(),
 
 	midpoint: function ( optionalTarget ) {
 
@@ -161,9 +187,4 @@ THREE.Triangle.prototype = {
 
 	}
 
-};
-
-THREE.Triangle.__v0 = new THREE.Vector3();
-THREE.Triangle.__v1 = new THREE.Vector3();
-THREE.Triangle.__v2 = new THREE.Vector3();
-THREE.Triangle.__v3 = new THREE.Vector3();
+} );

+ 2 - 4
src/math/Vector2.js

@@ -12,9 +12,7 @@ THREE.Vector2 = function ( x, y ) {
 
 };
 
-THREE.Vector2.prototype = {
-
-	constructor: THREE.Vector2,
+THREE.extend( THREE.Vector2.prototype, {
 
 	set: function ( x, y ) {
 
@@ -301,4 +299,4 @@ THREE.Vector2.prototype = {
 
 	}
 
-};
+} );

+ 41 - 15
src/math/Vector3.js

@@ -15,10 +15,7 @@ THREE.Vector3 = function ( x, y, z ) {
 
 };
 
-
-THREE.Vector3.prototype = {
-
-	constructor: THREE.Vector3,
+THREE.extend( THREE.Vector3.prototype, {
 
 	set: function ( x, y, z ) {
 
@@ -268,21 +265,52 @@ THREE.Vector3.prototype = {
 
 	},
 
-	applyEuler: function ( v, eulerOrder ) {
+	applyEuler: function() {
 
-		var quaternion = THREE.Vector3.__q1.setFromEuler( v, eulerOrder );
+		var q1 = new THREE.Quaternion();
 
-		this.applyQuaternion( quaternion );
+		return function ( v, eulerOrder ) {
 
-		return this;
+			var quaternion = q1.setFromEuler( v, eulerOrder );
 
-	},
+			this.applyQuaternion( quaternion );
+
+			return this;
+
+		};
+
+	}(),
+
+	applyAxisAngle: function() {
+
+		var q1 = new THREE.Quaternion();
+
+		return function ( axis, angle ) {
+
+			var quaternion = q1.setFromAxisAngle( axis, angle );
+
+			this.applyQuaternion( quaternion );
 
-	applyAxisAngle: function ( axis, angle ) {
+			return this;
 
-		var quaternion = THREE.Vector3.__q1.setFromAxisAngle( axis, angle );
+		};
 
-		this.applyQuaternion( quaternion );
+	}(),
+
+	transformDirection: function ( m ) {
+
+		// input: THREE.Matrix4 affine matrix
+		// vector interpreted as a direction
+
+		var x = this.x, y = this.y, z = this.z;
+
+		var e = m.elements;
+
+		this.x = e[0] * x + e[4] * y + e[8]  * z;
+		this.y = e[1] * x + e[5] * y + e[9]  * z;
+		this.z = e[2] * x + e[6] * y + e[10] * z;
+
+		this.normalize();
 
 		return this;
 
@@ -729,6 +757,4 @@ THREE.Vector3.prototype = {
 
 	}
 
-};
-
-THREE.Vector3.__q1 = new THREE.Quaternion();
+} );

+ 2 - 4
src/math/Vector4.js

@@ -15,9 +15,7 @@ THREE.Vector4 = function ( x, y, z, w ) {
 
 };
 
-THREE.Vector4.prototype = {
-
-	constructor: THREE.Vector4,
+THREE.extend( THREE.Vector4.prototype, {
 
 	set: function ( x, y, z, w ) {
 
@@ -553,4 +551,4 @@ THREE.Vector4.prototype = {
 
 	}
 
-};
+} );

+ 46 - 0
src/renderers/CanvasRenderer.js

@@ -29,6 +29,8 @@ THREE.CanvasRenderer = function ( parameters ) {
 	_contextLineWidth = null,
 	_contextLineCap = null,
 	_contextLineJoin = null,
+	_contextDashSize = null,
+	_contextGapSize = 0,
 
 	_v1, _v2, _v3, _v4,
 	_v5 = new THREE.RenderableVertex(),
@@ -89,6 +91,26 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 	_gradientMapQuality --; // Fix UVs
 
+	// dash+gap fallbacks for Firefox and everything else
+
+	if ( _context.setLineDash === undefined ) {
+
+		if ( _context.mozDash !== undefined ) {
+
+			_context.setLineDash = function ( values ) {
+
+				_context.mozDash = values[ 0 ] !== null ? values : null;
+
+			}
+
+		} else {
+
+			_context.setLineDash = function ( values ) {}
+
+		}
+
+	}
+
 	this.domElement = _canvas;
 
 	this.devicePixelRatio = parameters.devicePixelRatio !== undefined
@@ -573,6 +595,18 @@ THREE.CanvasRenderer = function ( parameters ) {
 				setLineCap( material.linecap );
 				setLineJoin( material.linejoin );
 				setStrokeStyle( material.color.getStyle() );
+				setDashAndGap( null, null );
+
+				_context.stroke();
+				_elemBox.expandByScalar( material.linewidth * 2 );
+
+			} else if ( material instanceof THREE.LineDashedMaterial ) {
+
+				setLineWidth( material.linewidth );
+				setLineCap( material.linecap );
+				setLineJoin( material.linejoin );
+				setStrokeStyle( material.color.getStyle() );
+				setDashAndGap( material.dashSize, material.gapSize );
 
 				_context.stroke();
 				_elemBox.expandByScalar( material.linewidth * 2 );
@@ -1260,4 +1294,16 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 	}
 
+	function setDashAndGap( dashSizeValue, gapSizeValue ) {
+
+		if ( _contextDashSize !== dashSizeValue || _contextGapSize !== gapSizeValue ) {
+
+			_context.setLineDash( [ dashSizeValue, gapSizeValue ] );
+			_contextDashSize = dashSizeValue;
+			_contextGapSize = gapSizeValue;
+
+		}
+
+	}
+
 };

+ 7 - 7
test/unit/unittests_sources.html

@@ -12,21 +12,21 @@
   <!-- add ThreeJS sources to test below -->
 
   <script src="../../src/Three.js"></script>
-  <script src="../../src/math/Math.js"></script>
+  <script src="../../src/math/Color.js"></script>
+  <script src="../../src/math/Quaternion.js"></script>
   <script src="../../src/math/Vector2.js"></script>
   <script src="../../src/math/Vector3.js"></script>
   <script src="../../src/math/Vector4.js"></script>
   <script src="../../src/math/Box2.js"></script>
   <script src="../../src/math/Box3.js"></script>
-  <script src="../../src/math/Plane.js"></script>
-  <script src="../../src/math/Ray.js"></script>
-  <script src="../../src/math/Sphere.js"></script>
-  <script src="../../src/math/Triangle.js"></script>
   <script src="../../src/math/Matrix3.js"></script>
   <script src="../../src/math/Matrix4.js"></script>
-  <script src="../../src/math/Color.js"></script>
-  <script src="../../src/math/Quaternion.js"></script>
+  <script src="../../src/math/Ray.js"></script>
   <script src="../../src/math/Frustum.js"></script>
+  <script src="../../src/math/Plane.js"></script>
+  <script src="../../src/math/Sphere.js"></script>
+  <script src="../../src/math/Math.js"></script>
+  <script src="../../src/math/Triangle.js"></script>
 
   <!-- add class-based unit tests below -->
 

+ 9 - 3
utils/build.py

@@ -1,10 +1,16 @@
 #!/usr/bin/env python
 
+import sys
+
+if sys.version_info < (2, 7):
+	print("This script requires at least Python 2.7.")
+	print("Please, update to a newer version: http://www.python.org/download/releases/")
+	exit()
+
 import argparse
 import json
 import os
 import shutil
-import sys
 import tempfile
 
 
@@ -49,8 +55,8 @@ def main(argv=None):
 	# save
 
 	if args.minify is False:
-			shutil.copy(path, output)
-			os.chmod(output, 0o664); # temp files would usually get 0600
+		shutil.copy(path, output)
+		os.chmod(output, 0o664); # temp files would usually get 0600
 
 	else:
 

+ 9 - 0
utils/editors/sublimetext2/README.md

@@ -0,0 +1,9 @@
+### How to install
+
+1. Compress `threejs.sublime-completions` into `threejs.sublime-package`.
+
+```shell
+zip threejs.sublime-package threejs.sublime-completions
+```
+
+2. Copy the compressed file into `Sublime Text 2/Pristine Packages`.

+ 126 - 0
utils/editors/sublimetext2/threejs.sublime-completions

@@ -0,0 +1,126 @@
+{
+	"scope": "source.js,source.js.embedded.html,source.coffee",
+	"version": "r55",
+	"completions":
+	[
+		{ "trigger": "THREE.extend", "contents": "THREE.extend( ${1:target}, ${2:other} )$0" },
+		{ "trigger": "THREE.Color", "contents": "THREE.Color( ${1:value} )$0" },
+		{ "trigger": "THREE.Vector2", "contents": "THREE.Vector2( ${1:x}, ${2:y} )$0" },
+		{ "trigger": "THREE.Vector3", "contents": "THREE.Vector3( ${1:x}, ${2:y}, ${3:z} )$0" },
+		{ "trigger": "THREE.Vector4", "contents": "THREE.Vector4( ${1:x}, ${2:y}, ${3:z}, ${4:w} )$0" },
+		{ "trigger": "THREE.Box2", "contents": "THREE.Box2( ${1:min}, ${2:max} )$0" },
+		{ "trigger": "THREE.Box3", "contents": "THREE.Box3( ${1:min}, ${2:max} )$0" },
+		{ "trigger": "THREE.Matrix3", "contents": "THREE.Matrix3( ${1:n11}, ${2:n12}, ${3:n13}, ${4:n21}, ${5:n22}, ${6:n23}, ${7:n31}, ${8:n32}, ${9:n33} )$0" },
+		{ "trigger": "THREE.Matrix4", "contents": "THREE.Matrix4( ${1:n11}, ${2:n12}, ${3:n13}, ${4:n14}, ${5:n21}, ${6:n22}, ${7:n23}, ${8:n24}, ${9:n31}, ${10:n32}, ${11:n33}, ${12:n34}, ${13:n41}, ${14:n42}, ${15:n43}, ${16:n44} )$0" },
+		{ "trigger": "THREE.Ray", "contents": "THREE.Ray( ${1:origin}, ${2:direction} )$0" },
+		{ "trigger": "THREE.Sphere", "contents": "THREE.Sphere( ${1:center}, ${2:radius} )$0" },
+		{ "trigger": "THREE.Frustum", "contents": "THREE.Frustum( ${1:p0}, ${2:p1}, ${3:p2}, ${4:p3}, ${5:p4}, ${6:p5} )$0" },
+		{ "trigger": "THREE.Plane", "contents": "THREE.Plane( ${1:normal}, ${2:constant} )$0" },
+		{ "trigger": "THREE.Spline", "contents": "THREE.Spline( ${1:points} )$0" },
+		{ "trigger": "THREE.Triangle", "contents": "THREE.Triangle( ${1:a}, ${2:b}, ${3:c} )$0" },
+		{ "trigger": "THREE.Vertex", "contents": "THREE.Vertex( ${1:v} )$0" },
+		{ "trigger": "THREE.UV", "contents": "THREE.UV( ${1:u}, ${2:v} )$0" },
+		{ "trigger": "THREE.Clock", "contents": "THREE.Clock( ${1:autoStart} )$0" },
+		{ "trigger": "THREE.EventDispatcher", "contents": "THREE.EventDispatcher()$0" },
+		{ "trigger": "THREE.Raycaster", "contents": "THREE.Raycaster( ${1:origin}, ${2:direction}, ${3:near}, ${4:far} )$0" },
+		{ "trigger": "THREE.Object3D", "contents": "THREE.Object3D()$0" },
+		{ "trigger": "THREE.Projector", "contents": "THREE.Projector()$0" },
+		{ "trigger": "THREE.Face3", "contents": "THREE.Face3( ${1:a}, ${2:b}, ${3:c}, ${4:normal}, ${5:color}, ${6:materialIndex} )$0" },
+		{ "trigger": "THREE.Face4", "contents": "THREE.Face4( ${1:a}, ${2:b}, ${3:c}, ${4:d}, ${5:normal}, ${6:color}, ${7:materialIndex} )$0" },
+		{ "trigger": "THREE.Geometry", "contents": "THREE.Geometry()$0" },
+		{ "trigger": "THREE.BufferGeometry", "contents": "THREE.BufferGeometry()$0" },
+		{ "trigger": "THREE.Camera", "contents": "THREE.Camera()$0" },
+		{ "trigger": "THREE.OrthographicCamera", "contents": "THREE.OrthographicCamera( ${1:left}, ${2:right}, ${3:top}, ${4:bottom}, ${5:near}, ${6:far} )$0" },
+		{ "trigger": "THREE.PerspectiveCamera", "contents": "THREE.PerspectiveCamera( ${1:fov}, ${2:aspect}, ${3:near}, ${4:far} )$0" },
+		{ "trigger": "THREE.Light", "contents": "THREE.Light( ${1:hex} )$0" },
+		{ "trigger": "THREE.AmbientLight", "contents": "THREE.AmbientLight( ${1:hex} )$0" },
+		{ "trigger": "THREE.AreaLight", "contents": "THREE.AreaLight( ${1:hex}, ${2:intensity} )$0" },
+		{ "trigger": "THREE.DirectionalLight", "contents": "THREE.DirectionalLight( ${1:hex}, ${2:intensity} )$0" },
+		{ "trigger": "THREE.HemisphereLight", "contents": "THREE.HemisphereLight( ${1:skyColorHex}, ${2:groundColorHex}, ${3:intensity} )$0" },
+		{ "trigger": "THREE.PointLight", "contents": "THREE.PointLight( ${1:hex}, ${2:intensity}, ${3:distance} )$0" },
+		{ "trigger": "THREE.SpotLight", "contents": "THREE.SpotLight( ${1:hex}, ${2:intensity}, ${3:distance}, ${4:angle}, ${5:exponent} )$0" },
+		{ "trigger": "THREE.Loader", "contents": "THREE.Loader( ${1:showStatus} )$0" },
+		{ "trigger": "THREE.ImageLoader", "contents": "THREE.ImageLoader()$0" },
+		{ "trigger": "THREE.JSONLoader", "contents": "THREE.JSONLoader( ${1:showStatus} )$0" },
+		{ "trigger": "THREE.LoadingMonitor", "contents": "THREE.LoadingMonitor()$0" },
+		{ "trigger": "THREE.SceneLoader", "contents": "THREE.SceneLoader()$0" },
+		{ "trigger": "THREE.TextureLoader", "contents": "THREE.TextureLoader()$0" },
+		{ "trigger": "THREE.Material", "contents": "THREE.Material()$0" },
+		{ "trigger": "THREE.LineBasicMaterial", "contents": "THREE.LineBasicMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.LineDashedMaterial", "contents": "THREE.LineDashedMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.MeshBasicMaterial", "contents": "THREE.MeshBasicMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.MeshLambertMaterial", "contents": "THREE.MeshLambertMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.MeshPhongMaterial", "contents": "THREE.MeshPhongMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.MeshDepthMaterial", "contents": "THREE.MeshDepthMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.MeshNormalMaterial", "contents": "THREE.MeshNormalMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.MeshFaceMaterial", "contents": "THREE.MeshFaceMaterial( ${1:materials} )$0" },
+		{ "trigger": "THREE.ParticleBasicMaterial", "contents": "THREE.ParticleBasicMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.ParticleCanvasMaterial", "contents": "THREE.ParticleCanvasMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.ShaderMaterial", "contents": "THREE.ShaderMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.SpriteMaterial", "contents": "THREE.SpriteMaterial( ${1:parameters} )$0" },
+		{ "trigger": "THREE.Texture", "contents": "THREE.Texture( ${1:image}, ${2:mapping}, ${3:wrapS}, ${4:wrapT}, ${5:magFilter}, ${6:minFilter}, ${7:format}, ${8:type}, ${9:anisotropy} )$0" },
+		{ "trigger": "THREE.CompressedTexture", "contents": "THREE.CompressedTexture( ${1:mipmaps}, ${2:width}, ${3:height}, ${4:format}, ${5:type}, ${6:mapping}, ${7:wrapS}, ${8:wrapT}, ${9:magFilter}, ${10:minFilter}, ${11:anisotropy} )$0" },
+		{ "trigger": "THREE.DataTexture", "contents": "THREE.DataTexture( ${1:data}, ${2:width}, ${3:height}, ${4:format}, ${5:type}, ${6:mapping}, ${7:wrapS}, ${8:wrapT}, ${9:magFilter}, ${10:minFilter}, ${11:anisotropy} )$0" },
+		{ "trigger": "THREE.Particle", "contents": "THREE.Particle( ${1:material} )$0" },
+		{ "trigger": "THREE.ParticleSystem", "contents": "THREE.ParticleSystem( ${1:geometry}, ${2:material} )$0" },
+		{ "trigger": "THREE.Line", "contents": "THREE.Line( ${1:geometry}, ${2:material}, ${3:type} )$0" },
+		{ "trigger": "THREE.Mesh", "contents": "THREE.Mesh( ${1:geometry}, ${2:material} )$0" },
+		{ "trigger": "THREE.SkinnedMesh", "contents": "THREE.SkinnedMesh( ${1:geometry}, ${2:material}, ${3:useVertexTexture} )$0" },
+		{ "trigger": "THREE.MorphAnimMesh", "contents": "THREE.MorphAnimMesh( ${1:geometry}, ${2:material} )$0" },
+		{ "trigger": "THREE.Ribbon", "contents": "THREE.Ribbon( ${1:geometry}, ${2:material} )$0" },
+		{ "trigger": "THREE.LOD", "contents": "THREE.LOD()$0" },
+		{ "trigger": "THREE.Sprite", "contents": "THREE.Sprite( ${1:material} )$0" },
+		{ "trigger": "THREE.Scene", "contents": "THREE.Scene()$0" },
+		{ "trigger": "THREE.Fog", "contents": "THREE.Fog( ${1:hex}, ${2:near}, ${3:far} )$0" },
+		{ "trigger": "THREE.FogExp2", "contents": "THREE.FogExp2( ${1:hex}, ${2:density} )$0" },
+		{ "trigger": "THREE.CanvasRenderer", "contents": "THREE.CanvasRenderer( ${1:parameters} )$0" },
+		{ "trigger": "THREE.WebGLRenderer", "contents": "THREE.WebGLRenderer( ${1:parameters} )$0" },
+		{ "trigger": "THREE.WebGLRenderTarget", "contents": "THREE.WebGLRenderTarget( ${1:width}, ${2:height}, ${3:options} )$0" },
+		{ "trigger": "THREE.WebGLRenderTargetCube", "contents": "THREE.WebGLRenderTargetCube( ${1:width}, ${2:height}, ${3:options} )$0" },
+		{ "trigger": "THREE.RenderableVertex", "contents": "THREE.RenderableVertex()$0" },
+		{ "trigger": "THREE.RenderableFace3", "contents": "THREE.RenderableFace3()$0" },
+		{ "trigger": "THREE.RenderableFace4", "contents": "THREE.RenderableFace4()$0" },
+		{ "trigger": "THREE.RenderableObject", "contents": "THREE.RenderableObject()$0" },
+		{ "trigger": "THREE.RenderableParticle", "contents": "THREE.RenderableParticle()$0" },
+		{ "trigger": "THREE.RenderableLine", "contents": "THREE.RenderableLine()$0" },
+		{ "trigger": "THREE.Curve", "contents": "THREE.Curve()$0" },
+		{ "trigger": "THREE.CurvePath", "contents": "THREE.CurvePath()$0" },
+		{ "trigger": "THREE.Gyroscope", "contents": "THREE.Gyroscope()$0" },
+		{ "trigger": "THREE.Path", "contents": "THREE.Path( ${1:points} )$0" },
+		{ "trigger": "THREE.Shape", "contents": "THREE.Shape()$0" },
+		{ "trigger": "THREE.Animation", "contents": "THREE.Animation( ${1:root}, ${2:name}, ${3:interpolationType} )$0" },
+		{ "trigger": "THREE.CubeCamera", "contents": "THREE.CubeCamera( ${1:near}, ${2:far}, ${3:cubeResolution} )$0" },
+		{ "trigger": "THREE.CombinedCamera", "contents": "THREE.CombinedCamera( ${1:width}, ${2:height}, ${3:fov}, ${4:near}, ${5:far}, ${6:orthoNear}, ${7:orthoFar} )$0" },
+		{ "trigger": "THREE.AsteriskGeometry", "contents": "THREE.AsteriskGeometry( ${1:innerRadius}, ${2:outerRadius} )$0" },
+		{ "trigger": "THREE.CircleGeometry", "contents": "THREE.CircleGeometry( ${1:radius}, ${2:segments}, ${3:thetaStart}, ${4:thetaLength} )$0" },
+		{ "trigger": "THREE.CubeGeometry", "contents": "THREE.CubeGeometry( ${1:width}, ${2:height}, ${3:depth}, ${4:widthSegments}, ${5:heightSegments}, ${6:depthSegments} )$0" },
+		{ "trigger": "THREE.CylinderGeometry", "contents": "THREE.CylinderGeometry( ${1:radiusTop}, ${2:radiusBottom}, ${3:height}, ${4:radiusSegments}, ${5:heightSegments}, ${6:openEnded} )$0" },
+		{ "trigger": "THREE.ExtrudeGeometry", "contents": "THREE.ExtrudeGeometry( ${1:shapes}, ${2:options} )$0" },
+		{ "trigger": "THREE.ShapeGeometry", "contents": "THREE.ShapeGeometry( ${1:shapes}, ${2:options} )$0" },
+		{ "trigger": "THREE.LatheGeometry", "contents": "THREE.LatheGeometry( ${1:points}, ${2:segments}, ${3:phiStart}, ${4:phiLength} )$0" },
+		{ "trigger": "THREE.PlaneGeometry", "contents": "THREE.PlaneGeometry( ${1:width}, ${2:height}, ${3:widthSegments}, ${4:heightSegments} )$0" },
+		{ "trigger": "THREE.SphereGeometry", "contents": "THREE.SphereGeometry( ${1:radius}, ${2:widthSegments}, ${3:heightSegments}, ${4:phiStart}, ${5:phiLength}, ${6:thetaStart}, ${7:thetaLength} )$0" },
+		{ "trigger": "THREE.TextGeometry", "contents": "THREE.TextGeometry( ${1:text}, ${2:parameters} )$0" },
+		{ "trigger": "THREE.TorusGeometry", "contents": "THREE.TorusGeometry( ${1:radius}, ${2:tube}, ${3:radialSegments}, ${4:tubularSegments}, ${5:arc} )$0" },
+		{ "trigger": "THREE.TorusKnotGeometry", "contents": "THREE.TorusKnotGeometry( ${1:radius}, ${2:tube}, ${3:radialSegments}, ${4:tubularSegments}, ${5:p}, ${6:q}, ${7:heightScale} )$0" },
+		{ "trigger": "THREE.PolyhedronGeometry", "contents": "THREE.PolyhedronGeometry( ${1:vertices}, ${2:faces}, ${3:radius}, ${4:detail} )$0" },
+		{ "trigger": "THREE.IcosahedronGeometry", "contents": "THREE.IcosahedronGeometry( ${1:radius}, ${2:detail} )$0" },
+		{ "trigger": "THREE.OctahedronGeometry", "contents": "THREE.OctahedronGeometry( ${1:radius}, ${2:detail} )$0" },
+		{ "trigger": "THREE.TetrahedronGeometry", "contents": "THREE.TetrahedronGeometry( ${1:radius}, ${2:detail} )$0" },
+		{ "trigger": "THREE.ParametricGeometry", "contents": "THREE.ParametricGeometry( ${1:func}, ${2:slices}, ${3:stacks}, ${4:useTris} )$0" },
+		{ "trigger": "THREE.AxisHelper", "contents": "THREE.AxisHelper( ${1:size} )$0" },
+		{ "trigger": "THREE.ArrowHelper", "contents": "THREE.ArrowHelper( ${1:dir}, ${2:origin}, ${3:length}, ${4:hex} )$0" },
+		{ "trigger": "THREE.CameraHelper", "contents": "THREE.CameraHelper( ${1:camera} )$0" },
+		{ "trigger": "THREE.DirectionalLightHelper", "contents": "THREE.DirectionalLightHelper( ${1:light}, ${2:sphereSize} )$0" },
+		{ "trigger": "THREE.HemisphereLightHelper", "contents": "THREE.HemisphereLightHelper( ${1:light}, ${2:sphereSize}, ${3:arrowLength}, ${4:domeSize} )$0" },
+		{ "trigger": "THREE.PointLightHelper", "contents": "THREE.PointLightHelper( ${1:light}, ${2:sphereSize} )$0" },
+		{ "trigger": "THREE.SpotLightHelper", "contents": "THREE.SpotLightHelper( ${1:light}, ${2:sphereSize} )$0" },
+		{ "trigger": "THREE.ImmediateRenderObject", "contents": "THREE.ImmediateRenderObject()$0" },
+		{ "trigger": "THREE.LensFlare", "contents": "THREE.LensFlare( ${1:texture}, ${2:size}, ${3:distance}, ${4:blending}, ${5:color} )$0" },
+		{ "trigger": "THREE.LensFlarePlugin", "contents": "THREE.LensFlarePlugin()$0" },
+		{ "trigger": "THREE.ShadowMapPlugin", "contents": "THREE.ShadowMapPlugin()$0" },
+		{ "trigger": "THREE.SpritePlugin", "contents": "THREE.SpritePlugin()$0" },
+		{ "trigger": "THREE.DepthPassPlugin", "contents": "THREE.DepthPassPlugin()$0" },
+		"THREE"
+	]
+}

+ 64 - 0
utils/sublime.py

@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+import sys
+
+if sys.version_info < (2, 7):
+	print("This script requires at least Python 2.7.")
+	print("Please, update to a newer version: http://www.python.org/download/releases/")
+	exit()
+
+import argparse
+import json
+import os
+import re
+import shutil
+import tempfile
+
+
+def main(argv=None):
+
+	parser = argparse.ArgumentParser()
+	parser.add_argument('--include', action='append', required=True)
+	parser.add_argument('--output', default='editors/sublimetext2/threejs.sublime-completions')
+
+	args = parser.parse_args()
+
+	output = args.output
+
+	# parsing
+
+	print(' * Generating ' + output)
+
+	fd, path = tempfile.mkstemp()
+	tmp = open(path, 'w')
+	tmp.write('{\n\t"scope": "source.js,source.js.embedded.html,source.coffee",\n\t"version": "r55",\n\t"completions":\n\t[\n')
+
+	for include in args.include:
+		with open('includes/' + include + '.json','r') as f: files = json.load(f)
+		for filename in files:
+			with open(filename, 'r') as f:
+				string = f.read()
+				match = re.search('THREE.(\w+)[\ ]+?=[\ ]+?function[\ ]+\(([\w\,\ ]+)?\)', string)
+				if match:
+					name = match.group(1)
+					parameters = match.group(2)
+					if parameters is None:
+						parameters = ''
+					else:
+						array = parameters.split( ',' )
+						for i in range(len(array)):
+							array[i] = '${'+str(i+1)+':'+array[i].strip()+'}' # ${1:param}
+						parameters = ' '+', '.join(array)+' '
+					tmp.write('\t\t{ "trigger": "THREE.'+name+'", "contents": "THREE.'+name+'('+parameters+')$0" },\n' )
+
+	tmp.write("\t\t\"THREE\"\n\t]\n}")
+	tmp.close()
+
+	# save
+
+	shutil.copy(path, output)
+	os.chmod(output, 0o664); # temp files would usually get 0600
+
+
+if __name__ == "__main__":
+	main()

+ 3 - 0
utils/sublime.sh

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+python sublime.py --include common --include extras --output editors/sublimetext2/threejs.sublime-completions

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio