浏览代码

Merge remote branch 'origin/dev' into documentation

OpenShift guest 12 年之前
父节点
当前提交
fe2d302a71

文件差异内容过多而无法显示
+ 365 - 257
build/three.js


文件差异内容过多而无法显示
+ 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.
 		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>
 		</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>
 		<h3>.[page:Array offsets]</h3>
 		<div>
 		<div>
 		This Array should contain every offset at which the buffers should be rendered. This is important for indexed buffers.
 		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
  * @author Larry Battle / http://bateru.com/news
  */
  */
 
 
-var THREE = THREE || { REVISION: '55' };
+var THREE = THREE || { REVISION: '56dev' };
 
 
 self.console = self.console || {
 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://paulirish.com/2011/requestanimationframe-for-smart-animating/
 // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-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
  * @author julianwa / https://github.com/julianwa
  */
  */
 
 
-THREE.Projector = function() {
+THREE.Projector = function () {
 
 
 	var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
 	var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
 	_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
 	_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,

+ 1 - 1
src/core/Raycaster.js

@@ -8,7 +8,7 @@
 	THREE.Raycaster = function ( origin, direction, near, far ) {
 	THREE.Raycaster = function ( origin, direction, near, far ) {
 
 
 		this.ray = new THREE.Ray( origin, direction );
 		this.ray = new THREE.Ray( origin, direction );
-		
+
 		// normalized ray.direction required for accurate distance calculations
 		// normalized ray.direction required for accurate distance calculations
 		if( this.ray.direction.length() > 0 ) {
 		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 3a - Extract points from each shape, turn to vertices
 // STEP 3b - Triangulate each shape, add faces.
 // STEP 3b - Triangulate each shape, add faces.
 
 
-THREE.Shape = function ( ) {
+THREE.Shape = function () {
 
 
 	THREE.Path.apply( this, arguments );
 	THREE.Path.apply( this, arguments );
 	this.holes = [];
 	this.holes = [];

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

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

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

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

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

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

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

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

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

@@ -3,7 +3,7 @@
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
  */
  */
 
 
-THREE.SpritePlugin = function ( ) {
+THREE.SpritePlugin = function () {
 
 
 	var _gl, _renderer, _precision, _sprite = {};
 	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 ) {
 	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 ) {
 	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 ) {
 	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 ) {
 	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 ) {
 	copy: function ( box ) {
 
 
@@ -215,27 +219,39 @@ THREE.Box3.prototype = {
 	clampPoint: function ( point, optionalTarget ) {
 	clampPoint: function ( point, optionalTarget ) {
 
 
 		var result = optionalTarget || new THREE.Vector3();
 		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 ) {
 	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 ) {
 	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,
 	r: 1, g: 1, b: 1,
 
 
-
 	set: function ( value ) {
 	set: function ( value ) {
 
 
 		switch ( typeof value ) {
 		switch ( typeof value ) {
@@ -390,7 +387,7 @@ THREE.Color.prototype = {
 
 
 	}
 	}
 
 
-};
+} );
 
 
 THREE.ColorKeywords = { "aliceblue": 0xF0F8FF, "antiquewhite": 0xFAEBD7, "aqua": 0x00FFFF, "aquamarine": 0x7FFFD4, "azure": 0xF0FFFF,
 THREE.ColorKeywords = { "aliceblue": 0xF0F8FF, "antiquewhite": 0xFAEBD7, "aqua": 0x00FFFF, "aquamarine": 0x7FFFD4, "azure": 0xF0FFFF,
 "beige": 0xF5F5DC, "bisque": 0xFFE4C4, "black": 0x000000, "blanchedalmond": 0xFFEBCD, "blue": 0x0000FF, "blueviolet": 0x8A2BE2,
 "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 ) {
 	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 ) {
 	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 ) {
 	multiplyScalar: function ( s ) {
 
 
@@ -164,7 +166,6 @@ THREE.Matrix3.prototype = {
 
 
 	},
 	},
 
 
-
 	transpose: function () {
 	transpose: function () {
 
 
 		var tmp, m = this.elements;
 		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 ) {
 	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 ) {
 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 ) {
 	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();
 			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 ) {
 	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 ) {
 	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 ) {
 	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() {
 	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 ) {
 	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 ) {
 	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 ) {
 	translate: function ( v ) {
 
 
@@ -904,8 +943,6 @@ THREE.Matrix4.prototype = {
 
 
 	},
 	},
 
 
-	//
-
 	makeTranslation: function ( x, y, z ) {
 	makeTranslation: function ( x, y, z ) {
 
 
 		this.set(
 		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 ) {
 	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 ) {
 	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 ) {
 	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 ) {
 	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 ) {
 	set: function ( x, y, z, w ) {
 
 
@@ -339,7 +337,7 @@ THREE.Quaternion.prototype = {
 
 
 	}
 	}
 
 
-}
+} );
 
 
 THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
 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 ) {
 	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 ) {
 	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 ) {
 	isIntersectionSphere: function( sphere ) {
 
 
@@ -121,7 +131,7 @@ THREE.Ray.prototype = {
 
 
 		var t = this.distanceToPlane( plane );
 		var t = this.distanceToPlane( plane );
 
 
-		if( t === undefined ) {
+		if ( t === undefined ) {
 
 
 			return 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 ) {
 	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
 // static/instance method to calculate barycoordinates
 // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
 // 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,
 	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 ) {
 	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 ) {
 	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 ) {
 	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;
 		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 ) {
 	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,
 	_contextLineWidth = null,
 	_contextLineCap = null,
 	_contextLineCap = null,
 	_contextLineJoin = null,
 	_contextLineJoin = null,
+	_contextDashSize = null,
+	_contextGapSize = 0,
 
 
 	_v1, _v2, _v3, _v4,
 	_v1, _v2, _v3, _v4,
 	_v5 = new THREE.RenderableVertex(),
 	_v5 = new THREE.RenderableVertex(),
@@ -89,6 +91,26 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 
 	_gradientMapQuality --; // Fix UVs
 	_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.domElement = _canvas;
 
 
 	this.devicePixelRatio = parameters.devicePixelRatio !== undefined
 	this.devicePixelRatio = parameters.devicePixelRatio !== undefined
@@ -573,6 +595,18 @@ THREE.CanvasRenderer = function ( parameters ) {
 				setLineCap( material.linecap );
 				setLineCap( material.linecap );
 				setLineJoin( material.linejoin );
 				setLineJoin( material.linejoin );
 				setStrokeStyle( material.color.getStyle() );
 				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();
 				_context.stroke();
 				_elemBox.expandByScalar( material.linewidth * 2 );
 				_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 -->
   <!-- add ThreeJS sources to test below -->
 
 
   <script src="../../src/Three.js"></script>
   <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/Vector2.js"></script>
   <script src="../../src/math/Vector3.js"></script>
   <script src="../../src/math/Vector3.js"></script>
   <script src="../../src/math/Vector4.js"></script>
   <script src="../../src/math/Vector4.js"></script>
   <script src="../../src/math/Box2.js"></script>
   <script src="../../src/math/Box2.js"></script>
   <script src="../../src/math/Box3.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/Matrix3.js"></script>
   <script src="../../src/math/Matrix4.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/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 -->
   <!-- add class-based unit tests below -->
 
 

+ 9 - 3
utils/build.py

@@ -1,10 +1,16 @@
 #!/usr/bin/env python
 #!/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 argparse
 import json
 import json
 import os
 import os
 import shutil
 import shutil
-import sys
 import tempfile
 import tempfile
 
 
 
 
@@ -49,8 +55,8 @@ def main(argv=None):
 	# save
 	# save
 
 
 	if args.minify is False:
 	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:
 	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

部分文件因为文件数量过多而无法显示