Procházet zdrojové kódy

Automated uniform.<name>.type. (#8606)

* MatrixN: Deprecated .flattenToArrayOffset.

Instead .toArray consistently allows array and offset to be passed.

* Updated math classes' docs .toArray / .fromArray.

* Automated uniform.<name>.type.

* WebGLRenderer: Added .setTexture deprecation stub.

* Updated ShaderMaterial docs, uniform types.

* Updated Quaternion docs .toArray / .fromArray.

* Updated Quaternion docs, static .slerpFlat.

* Updated math classes' docs, style consistency.

* Updated ShaderMaterial docs, style consistency.
tschw před 9 roky
rodič
revize
494e016dea

+ 112 - 25
docs/api/materials/ShaderMaterial.html

@@ -31,11 +31,11 @@
 		var material = new THREE.ShaderMaterial( {
 
 			uniforms: {
-				time: { type: "f", value: 1.0 },
-				resolution: { type: "v2", value: new THREE.Vector2() }
+				time: { value: 1.0 },
+				resolution: { value: new THREE.Vector2() }
 			},
 			attributes: {
-				vertexOpacity: { type: 'f', value: [] }
+				vertexOpacity: { value: [] }
 			},
 			vertexShader: document.getElementById( 'vertexShader' ).textContent,
 			fragmentShader: document.getElementById( 'fragmentShader' ).textContent
@@ -122,81 +122,168 @@
 		To declare a custom uniform, use the *uniforms* property:
 		<code>
 		uniforms: {
-			time: { type: "f", value: 1.0 },
-			resolution: { type: "v2", value: new THREE.Vector2() }
+			time: { value: 1.0 },
+			resolution: { value: new THREE.Vector2() }
 		}
 		</code>
-		Each uniform must have a <a href="#uniform-types">*type*</a> and a *value*:
+		Each uniform must have a *value* property. The type of the value must correspond to the type of the uniform variable in the GLSL code as specified for the primitive GLSL types in the table below. Uniform structures and arrays are also supported. GLSL arrays of primitive type must either be specified as an array of the corresponding THREE objects or as a flat array containing the data of all the objects. In other words; GLSL primitives in arrays must not be represented by arrays. This rule does not apply transitively.  An array of *vec2* arrays, each with a length of five vectors, must be an array of arrays, of either five *THREE.Vector2* objects or ten *number*s.
 		<table>
 			<caption><a id="uniform-types">Uniform types</a></caption>
 			<thead>
 				<tr>
-					<th>Uniform *type* string</th>
 					<th>GLSL type</th>
 					<th>JavaScript type</th>
 				</tr>
 			</thead>
 			<tbody>
+
 				<tr>
-					<td><code>'i', '1i'</code></td>
 					<td>int</td>
 					<td>[page:Number]</td>
 				</tr>
 				<tr>
-					<td><code>'f', '1f'</code></td>
 					<td>float</td>
 					<td>[page:Number]</td>
 				</tr>
 				<tr>
-					<td><code>'v2'</code></td>
+					<td>bool</td>
+					<td>[page:Boolean]</td>
+				</tr>
+				<tr>
+					<td>bool</td>
+					<td>[page:Number]</td>
+				</tr>
+
+				<tr>
 					<td>vec2</td>
 					<td>[page:Vector2 THREE.Vector2]</td>
 				</tr>
 				<tr>
-					<td><code>'v3'</code></td>
+					<td>vec2</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec2</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
 					<td>vec3</td>
 					<td>[page:Vector3 THREE.Vector3]</td>
 				</tr>
 				<tr>
-					<td><code>'c'</code></td>
 					<td>vec3</td>
 					<td>[page:Color THREE.Color]</td>
 				</tr>
-
 				<tr>
-					<td><code>'v4'</code></td>
+					<td>vec3</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec3</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
 					<td>vec4</td>
 					<td>[page:Vector4 THREE.Vector4]</td>
 				</tr>
+				<tr>
+					<td>vec4</td>
+					<td>[page:Quaternion THREE.Quaternion]</td>
+				</tr>
+				<tr>
+					<td>vec4</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec4</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
 
 				<tr>
-					<td><code>'m3'</code></td>
+					<td>mat2</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</td>
+				<tr>
+					<td>mat2</td>
+					<td>[page:Array Array] (*)</td>
+				</td>
+				<tr>
 					<td>mat3</td>
 					<td>[page:Matrix3 THREE.Matrix3]</td>
 				</tr>
-
 				<tr>
-					<td><code>'m4'</code></td>
+					<td>mat3</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>mat3</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
 					<td>mat4</td>
-					<td>[page:Matrix4 THREE.Matrix4]</td>
+					<td>[page:Matrix3 THREE.Matrix4]</td>
+				</tr>
+				<tr>
+					<td>mat4</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>mat4</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+
+				<tr>
+					<td>ivec2, bvec2</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec2, bvec2</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec3, bvec3</td>
+					<td>[page:Int32Array Int32Array] (*)</td>
 				</tr>
 				<tr>
-					<td><code>'t'</code></td>
+					<td>ivec3, bvec3</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec4, bvec4</td>
+					<td>[page:Int32Array Int32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec4, bvec4</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+
+				<tr>
 					<td>sampler2D</td>
 					<td>[page:Texture THREE.Texture]</td>
 				</tr>
 				<tr>
-					<td><code>'t'</code></td>
+					<td>sampler2D</td>
+					<td>[page:WebGLRenderTarget THREE.WebGLRenderTarget]</td>
+				</tr>
+				<tr>
+					<td>samplerCube</td>
+					<td>[page:CubeTexture THREE.CubeTexture]</tr>
+				</tr>
+				<tr>
 					<td>samplerCube</td>
-					<td>[page:Texture THREE.CubeTexture]</td>
+					<td>[page:WebGLRenderTargetCube THREE.WebGLRenderTargetCube]</td>
 				</tr>
+
 			</tbody>
 		</table>
 		</p>
+		<p>
+		(*) Same for an (innermost) array (dimension) of the same GLSL type, containing the components of all vectors or matrices in the array.
+		</p>
 
 		<h2>Constructor</h2>
 
-		<h3>[name]([page:Object parameters])</h3>
+		<h3>[name]( [page:Object parameters] )</h3>
 		<div>
 		parameters -- An object containing various parameters setting up shaders and their uniforms.
 		</div>
@@ -217,9 +304,9 @@
 		<div>
 		Object specifying the uniforms to be passed to the shader code; keys are uniform names, values are definitions of the form
 		<code>
-		{ type: 'f', value: 1.0 }
+		{ value: 1.0 }
 		</code>
-		where *type* is a <a href="#uniform-types">uniform type string</a>, and *value* is the value of the uniform. Names must match the name of the uniform, as defined in the GLSL code. Note that uniforms are refreshed on every frame, so updating the value of the uniform will immediately update the value available to the GLSL code.
+		where *value* is the value of the uniform. Names must match the name of the uniform, as defined in the GLSL code. Note that uniforms are refreshed on every frame, so updating the value of the uniform will immediately update the value available to the GLSL code.
 		</div>
 
 		<h3>[property:Object defines]</h3>
@@ -308,7 +395,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:ShaderMaterial clone]()</h3>
+		<h3>[method:ShaderMaterial clone]() [page:ShaderMaterial this]</h3>
 		<div>
 		Generates a shallow copy of this material. Note that the vertexShader and fragmentShader are copied <emph>by reference</emph>, as are the definitions of the *attributes*; this means that clones of the material will share the same compiled [page:WebGLProgram]. However, the *uniforms* are copied <emph>by value</emph>, which allows you to have different sets of uniforms for different copies of the material.
 		</div>

+ 22 - 12
docs/api/math/Color.html

@@ -51,6 +51,14 @@
 
 		<h2>Methods</h2>
 
+		<h3>[method:Color set]( value ) [page:Color this]</h3>
+		<div>
+		value -- either an instance of [page:Color], a [page:Integer hexadecimal] value, or a css style [page:String string]
+		</div>
+		<div>
+		Delegates to .copy, .setStyle, or .setHex depending on input type.
+		</div>
+
 		<h3>[method:Color copy]( [page:Color color] ) [page:Color this]</h3>
 		<div>
 		color — Color to copy.
@@ -59,6 +67,15 @@
 		Copies given color.
 		</div>
 
+		<h3>[method:Color fromArray]([page:Array array], [page:Integer offset]) [page:Color this]</h3>
+		<div>
+		array -- [page:Array] [r, g, b] <br />
+		offset -- [page:Integer] An optional offset into the array.
+		</div>
+		<div>
+		Sets this color's components based on an array formatted like [r, g, b]
+		</div>
+
 		<h3>[method:Color copyGammaToLinear]( [page:Color color] ) [page:Color this]</h3>
 		<div>
 		color — Color to copy.
@@ -179,30 +196,23 @@
 		Linear interpolation of this colors rgb values and the rgb values of the first argument. The alpha argument can be thought of as the percent between the two colors, where 0 is this color and 1 is the first argument.
 		</div>
 
-		<h3>[method:Array toArray]( [page:Array array] )</h3>
-		<div>
-		array -- Optional array to store the color.
-		</div>
-		<div>
-		Returns an array [r,g,b]
-		</div>
-
 		<h3>[method:Color equals]( [page:Color c] ) [page:Color this]</h3>
 		<div>
 		Compares this color and c and returns true if they are the same, false otherwise.
 		</div>
 
-		<h3>[method:Color clone]()</h3>
+		<h3>[method:Color clone]() [page:Color this]</h3>
 		<div>
 		Clones this color.
 		</div>
 
-		<h3>[method:Color set]( value ) [page:Color this]</h3>
+		<h3>[method:Array toArray]([page:Array array], [page:Integer offset]) [page:Color this]</h3>
 		<div>
-		value -- either an instance of [page:Color], a [page:Integer hexadecimal] value, or a css style [page:String string]
+		array -- An optional array to store the color to. <br />
+		offset -- An optional offset into the array.
 		</div>
 		<div>
-		Delegates to .copy, .setStyle, or .setHex depending on input type.
+		Returns an array [r,g,b]
 		</div>
 
 		<h2>Source</h2>

+ 50 - 34
docs/api/math/Matrix3.html

@@ -33,42 +33,57 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Matrix3 transpose]()</h3>
+		<h3>[method:Matrix3 set]( [page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33] ) [page:Matrix3 this]</h3>
 		<div>
-		Transposes this matrix in place.
+		n11 -- [page:Float] <br />
+		n12 -- [page:Float] <br />
+		n13 -- [page:Float] <br />
+		n21 -- [page:Float] <br />
+		n22 -- [page:Float] <br />
+		n23 -- [page:Float] <br />
+		n31 -- [page:Float] <br />
+		n32 -- [page:Float] <br />
+		n33 -- [page:Float]
+		</div>
+		<div>
+		Sets the 3x3 matrix values to the given row-major sequence of values.
 		</div>
 
-		<h3>[method:Matrix3 transposeIntoArray]( [page:Array array] )</h3>
+		<h3>[method:Matrix3 copy]( [page:Matrix3 m] ) [page:Matrix3 this]</h3>
 		<div>
-		array -- [page:Array] <br />
+		m -- [page:Matrix4]
 		</div>
 		<div>
-		Transposes this matrix into the supplied array, and returns itself unchanged.
+		Copies the values of matrix *m* into this matrix.
 		</div>
 
+		<h3>[method:Matrix3 fromArray]( [page:Array array] ) [page:Matrix3 this]</h3>
+		<div>
+		array -- [page:Array] The array to read the elements from.
+		</div>
+		<div>
+		Sets the elements of this matrix based on an array in column-major format.
+		</div>
 
-		<h3>[method:Float determinant]()</h3>
+		<h3>[method:Matrix3 transpose]() [page:Matrix3 this]</h3>
 		<div>
-		Computes and returns the determinant of this matrix.
+		Transposes this matrix in place.
 		</div>
 
-		<h3>[method:Matrix3 set]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 transposeIntoArray]( [page:Array array] ) [page:Matrix3 this]</h3>
 		<div>
-		n11 -- [page:Float] <br />
-		n12 -- [page:Float] <br />
-		n13 -- [page:Float] <br />
-		n21 -- [page:Float] <br />
-		n22 -- [page:Float] <br />
-		n23 -- [page:Float] <br />
-		n31 -- [page:Float] <br />
-		n32 -- [page:Float] <br />
-		n33 -- [page:Float]
+		array -- [page:Array] <br />
 		</div>
 		<div>
-		Sets the 3x3 matrix values to the given row-major sequence of values.
+		Transposes this matrix into the supplied array, and returns itself unchanged.
+		</div>
+
+		<h3>[method:Float determinant]() [page:Matrix3 this]</h3>
+		<div>
+		Computes and returns the determinant of this matrix.
 		</div>
 
-		<h3>[method:Matrix3 multiplyScalar]([page:Float s]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 multiplyScalar]( [page:Float s] ) [page:Matrix3 this]</h3>
 		<div>
 		scalar -- [page:Float]
 		</div>
@@ -76,7 +91,7 @@
 		Multiplies every component of the matrix by the scalar value *s*.
 		</div>
 
-		<h3>[method:Array applyToVector3Array]([page:Array array])</h3>
+		<h3>[method:Array applyToVector3Array]( [page:Array array] ) [page:Matrix3 this]</h3>
 		<div>
 		array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
 		</div>
@@ -84,7 +99,7 @@
 		Multiplies (applies) this matrix to every vector3 in the array.
 		</div>
 
-		<h3>[method:Matrix3 getNormalMatrix]([page:Matrix4 m]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 getNormalMatrix]( [page:Matrix4 m] ) [page:Matrix3 this]</h3>
 		<div>
 		m -- [page:Matrix4]
 		</div>
@@ -92,7 +107,7 @@
 		Sets this matrix as the normal matrix (upper left 3x3)of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix *m*.
 		</div>
 
-		<h3>[method:Matrix3 getInverse]([page:Matrix4 m], [page:Boolean throwOnDegenerate]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 getInverse]( [page:Matrix4 m], [page:Boolean throwOnDegenerate] ) [page:Matrix3 this]</h3>
 		<div>
 		m -- [page:Matrix4]<br />
 		throwOnDegenerate -- [Page:Boolean] If true, throw an error if the matrix is degenerate (not invertible).
@@ -101,26 +116,27 @@
 		Set this matrix to the inverse of the passed matrix.
 		</div>
 
-		<h3>[method:Matrix3 copy]([page:Matrix3 m]) [page:Matrix3 this]</h3>
-		<div>
-		m -- [page:Matrix4]
-		</div>
+		<h3>[method:Matrix3 identity]() [page:Matrix3 this]</h3>
 		<div>
-		Copies the values of matrix *m* into this matrix.
+		Resets this matrix to identity.<br/><br/>
+
+		1, 0, 0<br/>
+		0, 1, 0<br/>
+		0, 0, 1<br/>
 		</div>
 
-		<h3>[method:Matrix3 clone]()</h3>
+		<h3>[method:Matrix3 clone]() [page:Matrix3 this]</h3>
 		<div>
 		Creates a copy of this matrix.
 		</div>
 
-		<h3>[method:Matrix3 identity]() [page:Matrix3 this]</h3>
+		<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] ) [page:Matrix3 this]</h3>
 		<div>
-		Resets this matrix to identity.<br/><br/>
-
-		1, 0, 0<br/>
-		0, 1, 0<br/>
-		0, 0, 1<br/>
+		array -- [page:Array] optional array to store the vector <br />
+		offset -- [page:Integer] optional offset into the array
+		</div>
+		<div>
+		Writes the elements of this matrix to an array in column-major format.
 		</div>
 
 		<h2>Source</h2>

+ 26 - 14
docs/api/math/Matrix4.html

@@ -67,6 +67,14 @@
 		Copies the values of matrix *m* into this matrix.
 		</div>
 
+		<h3>[method:Matrix4 fromArray]( [page:Array array] ) [page:Matrix4 this]</h3>
+		<div>
+		array -- [page:Array] The array to read the elements from.
+		</div>
+		<div>
+		Sets the elements of this matrix based on an array in column-major format.
+		</div>
+
 		<h3>[method:Matrix4 copyPosition]( [page:Matrix4 m] ) [page:Matrix4 this]</h3>
 		<div>
 		Copies the translation component of the supplied matrix *m* into this matrix translation component.
@@ -118,7 +126,7 @@
 		Multiplies every component of the matrix by a scalar value *s*.
 		</div>
 
-		<h3>[method:Float determinant]()</h3>
+		<h3>[method:Float determinant]() [page:Matrix4 this]</h3>
 		<div>
 		Computes and returns the determinant of this matrix.<br />
 		Based on [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm]
@@ -129,11 +137,6 @@
 		Transposes this matrix.
 		</div>
 
-		<h3>[method:Array flattenToArrayOffset]( [page:Array flat], [page:Integer offset] )</h3>
-		<div>
-		Flattens this matrix into supplied *flat* array starting from *offset* position in the array.
-		</div>
-
 		<h3>[method:Matrix4 setPosition]( [page:Vector3 v] ) [page:Matrix4 this]</h3>
 		<div>
 		Sets the position component for this matrix from vector *v*.
@@ -169,7 +172,7 @@
 		Sets this matrix to the transformation composed of *translation*, *quaternion* and *scale*.
 		</div>
 
-		<h3>[method:Array decompose]( [page:Vector3 translation], [page:Quaternion quaternion], [page:Vector3 scale] )</h3>
+		<h3>[method:Array decompose]( [page:Vector3 translation], [page:Quaternion quaternion], [page:Vector3 scale] ) [page:Matrix4 this]</h3>
 		<div>
 		Decomposes this matrix into the *translation*, *quaternion* and *scale* components.
 		</div>
@@ -233,12 +236,7 @@
 		Creates an orthographic projection matrix.
 		</div>
 
-		<h3>[method:Matrix4 clone]()</h3>
-		<div>
-		Creates a copy of this matrix.
-		</div>
-
-		<h3>[method:Array applyToVector3Array]([page:Array a])</h3>
+		<h3>[method:Array applyToVector3Array]( [page:Array a] ) [page:Matrix4 this]</h3>
 		<div>
 		array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
 		</div>
@@ -246,11 +244,25 @@
 		Multiplies (applies) this matrix to every vector3 in the array.
 		</div>
 
-		<h3>[method:Float getMaxScaleOnAxis]()</h3>
+		<h3>[method:Float getMaxScaleOnAxis]() [page:Matrix4 this]</h3>
 		<div>
 		Gets the maximum scale value of the 3 axes.
 		</div>
 
+		<h3>[method:Matrix4 clone]() [page:Matrix4 this]</h3>
+		<div>
+		Creates a copy of this matrix.
+		</div>
+
+		<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] ) [page:Matrix4 this]</h3>
+		<div>
+		array -- [page:Array] optional array to store the vector <br />
+		offset -- [page:Integer] optional offset into the array
+		</div>
+		<div>
+		Writes the elements of this matrix to an array in column-major format.
+		</div>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 60 - 45
docs/api/math/Quaternion.html

@@ -48,115 +48,94 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Quaternion set]( [page:Float x], [page:Float y], [page:Float z], [page:Float w] )</h3>
+		<h3>[method:Quaternion set]( [page:Float x], [page:Float y], [page:Float z], [page:Float w] ) [page:Quaternion this]</h3>
 		<div>
 		Sets values of this quaternion.
 		</div>
 
-		<h3>[method:Quaternion copy]( [page:Quaternion q] )</h3>
+		<h3>[method:Quaternion copy]( [page:Quaternion q] ) [page:Quaternion this]</h3>
 		<div>
 		Copies values of *q* to this quaternion.
 		</div>
 
-		<h3>[method:Quaternion setFromEuler]( [page:Euler euler] )</h3>
+		<h3>[method:Quaternion fromArray]( [page:Array array], [page:Integer offset] ) [page:Quaternion this]</h3>
+		<div>
+		array -- Array of format (x, y, z, w) used to construct the quaternion.<br />
+		offset -- An optional offset into the array.
+		</div>
+		<div>
+		Sets this quaternion's component values from an array.
+		</div>
+
+		<h3>[method:Quaternion setFromEuler]( [page:Euler euler] ) [page:Quaternion this]</h3>
 		<div>
 		Sets this quaternion from rotation specified by Euler angle.
 		</div>
 
-		<h3>[method:Quaternion setFromAxisAngle]( [page:Vector3 axis], [page:Float angle] )</h3>
+		<h3>[method:Quaternion setFromAxisAngle]( [page:Vector3 axis], [page:Float angle] ) [page:Quaternion this]</h3>
 		<div>
 		Sets this quaternion from rotation specified by axis and angle.<br />
 		Adapted from [link:http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm].<br />
 		*Axis* is asumed to be normalized, *angle* is in radians.
 		</div>
 
-		<h3>[method:Quaternion setFromRotationMatrix]( [page:Matrix4 m] )</h3>
+		<h3>[method:Quaternion setFromRotationMatrix]( [page:Matrix4 m] ) [page:Quaternion this]</h3>
 		<div>
 		Sets this quaternion from rotation component of *m*.<br />
 		Adapted from [link:http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm].
 		</div>
 
-		<h3>[method:Quaternion setFromUnitVectors]( [page:Vector3 vFrom], [page:Vector3 vTo] )</h3>
+		<h3>[method:Quaternion setFromUnitVectors]( [page:Vector3 vFrom], [page:Vector3 vTo] ) [page:Quaternion this]</h3>
 		<div>
 		Sets this quaternion to the rotation required to rotate direction vector *vFrom* to direction vector *vTo*.<br />
 		Adapted from [link:http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors].<br />
 		*vFrom* and *vTo* are assumed to be normalized.
 		</div>
 
-		<h3>[method:Quaternion inverse]()</h3>
+		<h3>[method:Quaternion inverse]() [page:Quaternion this]</h3>
 		<div>
 		Inverts this quaternion.
 		</div>
 
-		<h3>[method:Float length]()</h3>
+		<h3>[method:Float length]() [page:Quaternion this]</h3>
 		<div>
 		Computes length of this quaternion.
 		</div>
 
-		<h3>[method:Quaternion normalize]()</h3>
+		<h3>[method:Quaternion normalize]() [page:Quaternion this]</h3>
 		<div>
 		Normalizes this quaternion.
 		</div>
 
-		<h3>[method:Quaternion multiply]( [page:Quaternion b] )</h3>
+		<h3>[method:Quaternion multiply]( [page:Quaternion b] ) [page:Quaternion this]</h3>
 		<div>
 		Multiplies this quaternion by *b*.
 		</div>
 
-		<h3>[method:Quaternion multiplyQuaternions]( [page:Quaternion a], [page:Quaternion b] )</h3>
+		<h3>[method:Quaternion multiplyQuaternions]( [page:Quaternion a], [page:Quaternion b] ) [page:Quaternion this]</h3>
 		<div>
 		Sets this quaternion to *a x b*<br />
 		Adapted from [link:http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm].
 		</div>
 
-		<h3>[method:Quaternion multiplyVector3]( [page:Vector3 vector], [page:Vector3 dest] )</h3>
+		<h3>[method:Quaternion multiplyVector3]( [page:Vector3 vector], [page:Vector3 dest] ) [page:Quaternion this]</h3>
 		<div>
 		Rotates *vector* by this quaternion into *dest*.<br />
 		If *dest* is not specified, result goes to *vec*.
 		</div>
 
-		<h3>[method:Quaternion clone]()</h3>
-		<div>
-		Clones this quaternion.
-		</div>
-
-		<h3>[method:Array toArray]( [page:Array array] )</h3>
-		<div>
-		array -- Array to store the quaternion.
-		</div>
-		<div>
-		Returns the numerical elements of this quaternion in an array of format (x, y, z, w).
-		</div>
-
-		<h3>[method:Boolean equals]([page:Quaternion v])</h3>
-		<div>
-		v -- Quaternion that this quaternion will be compared to.
-		</div>
-		<div>
-		Compares each component of *v* to each component of this quaternion to determine if they
-		represent the same rotation.
-		</div>
-
-		<h3>[method:Float lengthSq]()</h3>
+		<h3>[method:Float lengthSq]() [page:Quaternion this]</h3>
 		<div>
 		Calculates the squared length of the quaternion.
 		</div>
 
-		<h3>[method:Quaternion fromArray]([page:Array array])</h3>
-		<div>
-		array -- Array of format (x, y, z, w) used to construct the quaternion.
-		</div>
-		<div>
-		Sets this quaternion's component values from an array.
-		</div>
-
-		<h3>[method:Quaternion conjugate]()</h3>
+		<h3>[method:Quaternion conjugate]() [page:Quaternion this]</h3>
 		<div>
 		Returns the rotational conjugate of this quaternion. The conjugate of a quaternion
 		represents the same rotation in the opposite direction about the rotational axis.
 		</div>
 
-		<h3>[method:Quaternion slerp]([page:Quaternion quaternionB], [page:float t])</h3>
+		<h3>[method:Quaternion slerp]( [page:Quaternion quaternionB], [page:float t] ) [page:Quaternion this]</h3>
 		<div>
 		quaternionB -- The other quaternion rotation<br />
 		t -- Normalized 0 to 1 interpolation factor
@@ -171,6 +150,28 @@
 		mesh.quaternion.slerp( endQuaternion, 0.01 );
 		</code>
 
+		<h3>[method:Boolean equals]( [page:Quaternion v] ) [page:Quaternion this]</h3>
+		<div>
+		v -- Quaternion that this quaternion will be compared to.
+		</div>
+		<div>
+		Compares each component of *v* to each component of this quaternion to determine if they
+		represent the same rotation.
+		</div>
+
+		<h3>[method:Quaternion clone]() [page:Quaternion this]</h3>
+		<div>
+		Clones this quaternion.
+		</div>
+
+		<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] ) [page:Quaternion this]</h3>
+		<div>
+		array -- An optional array to store the quaternion.<br/>
+		offset -- An optional offset into the output array.
+		</div>
+		<div>
+		Returns the numerical elements of this quaternion in an array of format (x, y, z, w).
+		</div>
 
 		<h2>Static Methods</h2>
 
@@ -196,6 +197,20 @@
 		THREE.Quaternion.slerp( startQuaternion, endQuaternion, mesh.quaternion, t );
 		</code>
 
+		<h3>[method:Quaternion slerpFlat]( [page:Array dst], [page:Integer dstOffset], [page:Array src0], [page:Integer srcOffset0], [page:Array src1], [page:Integer srcOffset1], [page:Float t] )</h3>
+		<div>
+		dst -- The output array.<br />
+		dstOffset -- An offset into the output array.<br />
+		src0 -- The source array of the starting quaternion.<br />
+		srcOffset0 -- An offset into the array *src0*.<br />
+		src1 -- The source array of the target quatnerion.<br />
+		srcOffset1 -- An offset into the array *src1*.<br />
+		t -- Interpolation factor 0 at start, 1 at end.
+		</div>
+		<div>
+		Like the static *slerp* method above, but operates directly on flat arrays of numbers.
+		</div>
+
 		<!-- Note: Do not add non-static methods to the bottom of this page. Put them above the <h2>Static Methods</h2> -->
 
 		<h2>Source</h2>

+ 53 - 52
docs/api/math/Vector2.html

@@ -48,11 +48,36 @@
 		Sets value of this vector.
 		</div>
 
+		<h3>[method:Vector2 setX]( [page:Float x] ) [page:Vector2 this]</h3>
+		<div>
+		x -- [page:Float]
+		</div>
+		<div>
+		replace this vector's x value with x.
+		</div>
+
+		<h3>[method:Vector2 setY]( [page:Float y] ) [page:Vector2 this]</h3>
+		<div>
+		y -- [page:Float]
+		</div>
+		<div>
+		replace this vector's y value with y.
+		</div>
+
 		<h3>[method:Vector2 copy]( [page:Vector2 v] ) [page:Vector2 this]</h3>
 		<div>
 		Copies value of *v* to this vector.
 		</div>
 
+		<h3>[method:Vector2 fromArray]( [page:Array array], [page:Integer offset] ) [page:Vector2 this]</h3>
+		<div>
+		array -- The source array of length 2 <br />
+		offset -- An optional offset into the array.
+		</div>
+		<div>
+		Sets this vector's x value to be array[0] and y value to be array[1].
+		</div>
+
 		<h3>[method:Vector2 add]( [page:Vector2 v] ) [page:Vector2 this]</h3>
 		<div>
 		Adds *v* to this vector.
@@ -94,22 +119,22 @@
 		Inverts this vector.
 		</div>
 
-		<h3>[method:Float dot]( [page:Vector2 v] )</h3>
+		<h3>[method:Float dot]( [page:Vector2 v] ) [page:Vector2 this]</h3>
 		<div>
 		Computes dot product of this vector and *v*.
 		</div>
 
-		<h3>[method:Float lengthSq]()</h3>
+		<h3>[method:Float lengthSq]() [page:Vector2 this]</h3>
 		<div>
 		Computes squared length of this vector.
 		</div>
 
-		<h3>[method:Float length]()</h3>
+		<h3>[method:Float length]() [page:Vector2 this]</h3>
 		<div>
 		Computes length of this vector.
 		</div>
 
-		<h3>[method:Float lengthManhattan]()</h3>
+		<h3>[method:Float lengthManhattan]() [page:Vector2 this]</h3>
 		<div>
 		Computes Manhattan length of this vector.<br />
 		[link:http://en.wikipedia.org/wiki/Taxicab_geometry]
@@ -120,7 +145,7 @@
 		Normalizes this vector.
 		</div>
 
-		<h3>[method:Float angle]()</h3>
+		<h3>[method:Float angle]() [page:Vector2 this]</h3>
 		<div>
 		Computes the angle in radians of this vector with respect to the positive x-axis.
 		</div>
@@ -140,18 +165,7 @@
 		Normalizes this vector and multiplies it by *l*.
 		</div>
 
-		<h3>[method:Boolean equals]( [page:Vector2 v] )</h3>
-		<div>
-		Checks for strict equality of this vector and *v*.
-		</div>
-
-		<h3>[method:Vector2 clone]()</h3>
-		<div>
-		Clones this vector.
-		</div>
-
-
-		<h3>[method:Vector2 clamp]([page:Vector2 min], [page:Vector2 max]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 clamp]( [page:Vector2 min], [page:Vector2 max] ) [page:Vector2 this]</h3>
 		<div>
 		min -- [page:Vector2] containing the min x and y values in the desired range <br />
 		max -- [page:Vector2] containing the max x and y values in the desired range
@@ -161,7 +175,7 @@
 		If this vector's x or y value is less than the min vector's x or y value, it is replaced by the corresponding value.
 		</div>
 
-		<h3>[method:Vector2 clampScalar]([page:Float min], [page:Float max]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 clampScalar]( [page:Float min], [page:Float max] ) [page:Vector2 this]</h3>
 		<div>
 		min -- [page:Float] the minimum value the components will be clamped to <br />
 		max -- [page:Float] the maximum value the components will be clamped to
@@ -171,7 +185,7 @@
 		If this vector's x or y values are less than the min value, they are replaced by the min value.
 		</div>
 
-		<h3>[method:Vector2 clampLength]([page:Float min], [page:Float max]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 clampLength]( [page:Float min], [page:Float max] ) [page:Vector2 this]</h3>
 		<div>
 		min -- [page:Float] the minimum value the length will be clamped to <br />
 		max -- [page:Float] the maximum value the length will be clamped to
@@ -181,27 +195,27 @@
 		If this vector's length is less than the min value, it is replaced by the min value.
 		</div>
 
-		<h3>[method:Vector2 floor]()</h3>
+		<h3>[method:Vector2 floor]() [page:Vector2 this]</h3>
 		<div>
 		The components of the vector are rounded downwards (towards negative infinity) to an integer value.
 		</div>
 
-		<h3>[method:Vector2 ceil]()</h3>
+		<h3>[method:Vector2 ceil]() [page:Vector2 this]</h3>
 		<div>
 		The components of the vector are rounded upwards (towards positive infinity) to an integer value.
 		</div>
 
-		<h3>[method:Vector2 round]()</h3>
+		<h3>[method:Vector2 round]() [page:Vector2 this]</h3>
 		<div>
 		The components of the vector are rounded towards the nearest integer value.
 		</div>
 
-		<h3>[method:Vector2 roundToZero]()</h3>
+		<h3>[method:Vector2 roundToZero]() [page:Vector2 this]</h3>
 		<div>
 		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
 		</div>
 
-		<h3>[method:Vector2 lerp]([page:Vector2 v], [page:Float alpha]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 lerp]( [page:Vector2 v], [page:Float alpha] ) [page:Vector2 this]</h3>
 		<div>
 		v -- [page:Vector2] <br />
 		alpha -- [page:Float] between 0 and 1;
@@ -210,7 +224,7 @@
 		Linear interpolation between this vector and v, where alpha is the percent along the line.
 		</div>
 
-		<h3>[method:Vector2 lerpVectors]([page:Vector2 v1], [page:Vector2 v2], [page:Float alpha]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 lerpVectors]( [page:Vector2 v1], [page:Vector2 v2], [page:Float alpha] ) [page:Vector2 this]</h3>
 		<div>
 		v1 -- [page:Vector2] <br />
 		v2 -- [page:Vector2] <br />
@@ -220,7 +234,7 @@
 		Sets this vector to be the vector linearly interpolated between *v1* and *v2* with *alpha* factor.
 		</div>
 
-		<h3>[method:undefined setComponent]([page:Integer index], [page:Float value])</h3>
+		<h3>[method:undefined setComponent]( [page:Integer index], [page:Float value] ) [page:Vector2 this]</h3>
 		<div>
 		index -- 0 or 1 <br />
 		value -- [page:Float]
@@ -230,7 +244,7 @@
 		if index equals 1 method replaces this.y with value.
 		</div>
 
-		<h3>[method:Vector2 addScalar]([page:Float s]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 addScalar]( [page:Float s] ) [page:Vector2 this]</h3>
 		<div>
 		s -- [page:Float]
 		</div>
@@ -238,7 +252,7 @@
 		Add the scalar value s to this vector's x and y values.
 		</div>
 
-		<h3>[method:Float getComponent]([page:Integer index])</h3>
+		<h3>[method:Float getComponent]( [page:Integer index] ) [page:Vector2 this]</h3>
 		<div>
 		index -- 0 or 1
 		</div>
@@ -247,23 +261,7 @@
 		if index equals 1 returns the y value.
 		</div>
 
-		<h3>[method:Vector2 fromArray]([page:Array array]) [page:Vector2 this]</h3>
-		<div>
-		array -- [page:Array] of length 2
-		</div>
-		<div>
-		Sets this vector's x value to be array[0] and y value to be array[1].
-		</div>
-
-		<h3>[method:Array toArray]( [page:Array array] )</h3>
-		<div>
-		array -- Optional array to store the vector.
-		</div>
-		<div>
-		Returns an array [x, y].
-		</div>
-
-		<h3>[method:Vector2 min]([page:Vector2 v]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 min]( [page:Vector2 v] ) [page:Vector2 this]</h3>
 		<div>
 		v -- [page:Vector2]
 		</div>
@@ -271,7 +269,7 @@
 		If this vector's x or y value is greater than v's x or y value, replace that value with the corresponding min value.
 		</div>
 
-		<h3>[method:Vector2 max]([page:Vector2 v]) [page:Vector2 this]</h3>
+		<h3>[method:Vector2 max]( [page:Vector2 v] ) [page:Vector2 this]</h3>
 		<div>
 		v -- [page:Vector2]
 		</div>
@@ -279,20 +277,23 @@
 		If this vector's x or y value is less than v's x or y value, replace that value with the corresponding max value.
 		</div>
 
-		<h3>[method:Vector2 setX]([page:Float x]) [page:Vector2 this]</h3>
+		<h3>[method:Boolean equals]( [page:Vector2 v] ) [page:Vector2 this]</h3>
 		<div>
-		x -- [page:Float]
+		Checks for strict equality of this vector and *v*.
 		</div>
+
+		<h3>[method:Vector2 clone]() [page:Vector2 this]</h3>
 		<div>
-		replace this vector's x value with x.
+		Clones this vector.
 		</div>
 
-		<h3>[method:Vector2 setY]([page:Float y]) [page:Vector2 this]</h3>
+		<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] ) [page:Vector2 this]</h3>
 		<div>
-		y -- [page:Float]
+		array -- An optional array to store the vector to. <br />
+		offset -- An optional offset into the array.
 		</div>
 		<div>
-		replace this vector's y value with y.
+		Returns an array [x, y].
 		</div>
 
 		<h2>Source</h2>

+ 68 - 67
docs/api/math/Vector3.html

@@ -73,6 +73,15 @@
 		Copies value of *v* to this vector.
 		</div>
 
+		<h3>[method:Vector3 fromArray]( [page:Array array], [page:Integer offset] ) [page:Vector3 this]</h3>
+		<div>
+		array -- The source array in the form [x, y, z].<br />
+		offset -- An optional offset into the array.
+		</div>
+		<div>
+		Sets the vector's components based on an array formatted like [x, y, z]
+		</div>
+
 		<h3>[method:Vector3 add]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		Adds *v* to this vector.
@@ -114,22 +123,22 @@
 		Inverts this vector.
 		</div>
 
-		<h3>[method:Float dot]( [page:Vector3 v] )</h3>
+		<h3>[method:Float dot]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		Computes dot product of this vector and *v*.
 		</div>
 
-		<h3>[method:Float lengthSq]()</h3>
+		<h3>[method:Float lengthSq]() [page:Vector3 this]</h3>
 		<div>
 		Computes squared length of this vector.
 		</div>
 
-		<h3>[method:Float length]()</h3>
+		<h3>[method:Float length]() [page:Vector3 this]</h3>
 		<div>
 		Computes length of this vector.
 		</div>
 
-		<h3>[method:Float lengthManhattan]()</h3>
+		<h3>[method:Float lengthManhattan]() [page:Vector3 this]</h3>
 		<div>
 		Computes Manhattan length of this vector.<br />
 		[link:http://en.wikipedia.org/wiki/Taxicab_geometry]
@@ -140,12 +149,12 @@
 		Normalizes this vector. Transforms this Vector into a Unit vector by dividing the vector by it's length.
 		</div>
 
-		<h3>[method:Float distanceTo]( [page:Vector3 v] )</h3>
+		<h3>[method:Float distanceTo]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		Computes distance of this vector to *v*.
 		</div>
 
-		<h3>[method:Float distanceToSquared]( [page:Vector3 v] )</h3>
+		<h3>[method:Float distanceToSquared]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		Computes squared distance of this vector to *v*.
 		</div>
@@ -175,18 +184,7 @@
 		Sets this vector extracting scale from matrix transform.
 		</div>
 
-		<h3>[method:Boolean equals]( [page:Vector3 v] )</h3>
-		<div>
-		Checks for strict equality of this vector and *v*.
-		</div>
-
-		<h3>[method:Vector3 clone]()</h3>
-		<div>
-		Clones this vector.
-		</div>
-
-
-		<h3>[method:Vector3 clamp]([page:Vector3 min], [page:Vector3 max]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 clamp]( [page:Vector3 min], [page:Vector3 max] ) [page:Vector3 this]</h3>
 		<div>
 		min -- [page:Vector3] <br />
 		max -- [page:Vector3]
@@ -196,7 +194,7 @@
 		If this vector's x, y or z value is less than the min vector's x, y or z value, it is replaced by the corresponding value.
 		</div>
 
-		<h3>[method:Vector3 clampScalar]([page:Float min], [page:Float max]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 clampScalar]( [page:Float min], [page:Float max] ) [page:Vector3 this]</h3>
 		<div>
 		min -- [page:Float] the minimum value the components will be clamped to <br />
 		max -- [page:Float] the maximum value the components will be clamped to
@@ -206,7 +204,7 @@
 		If this vector's x, y or z values are less than the min value, they are replaced by the min value.
 		</div>
 
-		<h3>[method:Vector3 clampLength]([page:Float min], [page:Float max]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 clampLength]( [page:Float min], [page:Float max] ) [page:Vector3 this]</h3>
 		<div>
 		min -- [page:Float] the minimum value the length will be clamped to <br />
 		max -- [page:Float] the maximum value the length will be clamped to
@@ -216,27 +214,27 @@
 		If this vector's length is less than the min value, it is replaced by the min value.
 		</div>
 
-		<h3>[method:Vector3 floor]()</h3>
+		<h3>[method:Vector3 floor]() [page:Vector3 this]</h3>
 		<div>
 		The components of the vector are rounded downwards (towards negative infinity) to an integer value.
 		</div>
 
-		<h3>[method:Vector3 ceil]()</h3>
+		<h3>[method:Vector3 ceil]() [page:Vector3 this]</h3>
 		<div>
 		The components of the vector are rounded upwards (towards positive infinity) to an integer value.
 		</div>
 
-		<h3>[method:Vector3 round]()</h3>
+		<h3>[method:Vector3 round]() [page:Vector3 this]</h3>
 		<div>
 		The components of the vector are rounded towards the nearest integer value.
 		</div>
 
-		<h3>[method:Vector3 roundToZero]()</h3>
+		<h3>[method:Vector3 roundToZero]() [page:Vector3 this]</h3>
 		<div>
 		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
 		</div>
 
-		<h3>[method:Vector3 applyMatrix3]([page:Matrix3 m]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 applyMatrix3]( [page:Matrix3 m] ) [page:Vector3 this]</h3>
 		<div>
 		m -- [page:Matrix3]
 		</div>
@@ -244,7 +242,7 @@
 		Multiplies this vector times a 3 x 3 matrix.
 		</div>
 
-		<h3>[method:Vector3 applyMatrix4]([page:Matrix3 m]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 applyMatrix4]( [page:Matrix3 m] ) [page:Vector3 this]</h3>
 		<div>
 		m -- [page:Matrix4]
 		</div>
@@ -252,7 +250,7 @@
 		Multiplies this vector by 4 x 3 subset of a Matrix4.
 		</div>
 
-		<h3>[method:Vector3 projectOnPlane]([page:Vector3 planeNormal]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 projectOnPlane]( [page:Vector3 planeNormal] ) [page:Vector3 this]</h3>
 		<div>
 		planeNormal -- [page:Vector3 planeNormal] A vector representing a plane normal.
 		</div>
@@ -260,7 +258,7 @@
 		Projects this vector onto a plane by subtracting this vector projected onto the plane's normal from this vector.
 		</div>
 
-		<h3>[method:Vector3 projectOnVector]([page:Vector3]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 projectOnVector]( [page:Vector3] ) [page:Vector3 this]</h3>
 		<div>
 		vector -- [page:Vector3]
 		</div>
@@ -268,7 +266,7 @@
 		Projects this vector onto another vector.
 		</div>
 
-		<h3>[method:Vector3 addScalar]([page:Float]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 addScalar]( [page:Float] ) [page:Vector3 this]</h3>
 		<div>
 		s -- [page:Float]
 		</div>
@@ -276,7 +274,7 @@
 		Adds a s to this vector.
 		</div>
 
-		<h3>[method:Vector3 divide]([page:Vector3 v]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 divide]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		v -- [page:Vector3]
 		</div>
@@ -284,7 +282,7 @@
 		Divides this vector by vector v.
 		</div>
 
-		<h3>[method:Vector3 min]([page:Vector3 v]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 min]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		v -- [page:Vector3]
 		</div>
@@ -292,7 +290,7 @@
 		If this vector's x, y, or z value is greater than vector v's x, y, or z value, that value is replaced by the corresponding vector v value.
 		</div>
 
-		<h3>[method:Vector3 max]([page:Vector3 v]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 max]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		v -- [page:Vector3]
 		</div>
@@ -300,7 +298,7 @@
 		If this vector's x, y, or z value is less than vector v's x, y, or z value, that value is replaced by the corresponding vector v value.
 		</div>
 
-		<h3>[method:Vector3 setComponent]([page:Integer index], [page:Float value]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 setComponent]( [page:Integer index], [page:Float value] ) [page:Vector3 this]</h3>
 		<div>
 		index -- 0, 1, or 2 <br />
 		value -- [page:Float]
@@ -311,7 +309,7 @@
 		If index equals 2 the method sets this vector's z value to value
 		</div>
 
-		<h3>[method:Vector3 transformDirection]([page:Matrix4 m]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 transformDirection]( [page:Matrix4 m] ) [page:Vector3 this]</h3>
 		<div>
 		m -- [page:Matrix4]
 		</div>
@@ -319,7 +317,7 @@
 		Transforms the direction of this vector by a matrix (a 3 x 3 subset of a Matrix4) and then normalizes the result.
 		</div>
 
-		<h3>[method:Vector3 multiplyVectors]([page:Vector3 a], [page:Vector3 b]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 multiplyVectors]( [page:Vector3 a], [page:Vector3 b] ) [page:Vector3 this]</h3>
 		<div>
 		a -- [page:Vector3] <br />
 		b -- [page:Vector3]
@@ -328,7 +326,7 @@
 		Sets this vector equal to the result of multiplying vector a by vector b.
 		</div>
 
-		<h3>[method:Float getComponent]([page:Integer index])</h3>
+		<h3>[method:Float getComponent]( [page:Integer index] ) [page:Vector3 this]</h3>
 		<div>
 		index -- [page:Integer] 0, 1, or 2
 		</div>
@@ -341,7 +339,7 @@
 		Index 2: z <br />
 		</div>
 
-		<h3>[method:Vector3 applyAxisAngle]([page:Vector3 axis], [page:Float angle]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 applyAxisAngle]( [page:Vector3 axis], [page:Float angle] ) [page:Vector3 this]</h3>
 		<div>
 		axis -- A normalized [page:Vector3] <br />
 		angle -- An angle in radians
@@ -350,7 +348,7 @@
 		Applies a rotation specified by an axis and an angle to this vector.
 		</div>
 
-		<h3>[method:Vector3 lerp]([page:Vector3 v], [page:Float alpha]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 lerp]( [page:Vector3 v], [page:Float alpha] ) [page:Vector3 this]</h3>
 		<div>
 		v -- [page:Vector3] <br />
 		alpha -- [page:Float] between 0 and 1.
@@ -359,7 +357,7 @@
 		Linear Interpolation between this vector and vector v, where alpha is the percent along the line.
 		</div>
 
-		<h3>[method:Vector3 lerpVectors]([page:Vector3 v1], [page:Vector3 v2], [page:Float alpha]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 lerpVectors]( [page:Vector3 v1], [page:Vector3 v2], [page:Float alpha] ) [page:Vector3 this]</h3>
 		<div>
 		v1 -- [page:Vector3] <br />
 		v2 -- [page:Vector3] <br />
@@ -369,7 +367,7 @@
 		Sets this vector to be the vector linearly interpolated between *v1* and *v2* with *alpha* factor.
 		</div>
 
-		<h3>[method:Float angleTo]([page:Vector3 v])</h3>
+		<h3>[method:Float angleTo]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		v -- [page:Vector3]
 		</div>
@@ -377,7 +375,7 @@
 		Returns the angle between this vector and vector v in radians.
 		</div>
 
-		<h3>[method:Vector3 setFromMatrixColumn]([page:Integer index], [page:Matrix4 matrix]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 setFromMatrixColumn]( [page:Integer index], [page:Matrix4 matrix] ) [page:Vector3 this]</h3>
 		<div>
 		index -- 0, 1, 2, or 3 <br />
 		matrix -- [page:Matrix4]
@@ -386,7 +384,7 @@
 		Sets this vector's x, y, and z equal to the column of the matrix specified by the index.
 		</div>
 
-		<h3>[method:Vector3 reflect]([page:Vector3 normal]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 reflect]( [page:Vector3 normal] ) [page:Vector3 this]</h3>
 		<div>
 		normal -- [page:Vector3] the normal to the reflecting plane
 		</div>
@@ -394,15 +392,7 @@
 		Reflect incident vector off of plane orthogonal to normal. normal is assumed to have unit length.
 		</div>
 
-		<h3>[method:Vector3 fromArray]([page:Array array]) [page:Vector3 this]</h3>
-		<div>
-		array -- [page:Array] [x, y, z]
-		</div>
-		<div>
-		Sets the vector's components based on an array formatted like [x, y, z]
-		</div>
-
-		<h3>[method:Vector3 multiply]([page:Vector3 v]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 multiply]( [page:Vector3 v] ) [page:Vector3 this]</h3>
 		<div>
 		v -- [page:Vector3] <br />
 		</div>
@@ -410,7 +400,7 @@
 		Multipies this vector by vector v.
 		</div>
 
-		<h3>[method:Vector3 applyProjection]([page:Matrix4 m]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 applyProjection]( [page:Matrix4 m] ) [page:Vector3 this]</h3>
 		<div>
 		m -- [page:Matrix4] projection matrix.
 		</div>
@@ -418,18 +408,7 @@
 		Multiplies this vector and m, and divides by perspective.
 		</div>
 
-		<h3>[method:Array toArray]( [page:Array array] )</h3>
-		<div>
-		array -- Optional array to store the vector.
-		</div>
-		<div>
-		Assigns this vector's x value to array[0]. <br />
-		Assigns this vector's y value to array[1]. <br />
-		Assigns this vector's z value to array[2]. <br />
-		Returns the created array.
-		</div>
-
-		<h3>[method:Vector3 applyEuler]([page:Euler euler]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 applyEuler]( [page:Euler euler] ) [page:Vector3 this]</h3>
 		<div>
 		euler -- [page:Euler]
 		</div>
@@ -437,7 +416,7 @@
 		Applies euler transform to this vector by converting the [page:Euler] obect to a [page:Quaternion] and applying.
 		</div>
 
-		<h3>[method:Vector3 applyQuaternion]([page:Quaternion quaternion]) [page:Vector3 this]</h3>
+		<h3>[method:Vector3 applyQuaternion]( [page:Quaternion quaternion] ) [page:Vector3 this]</h3>
 		<div>
 		quaternion -- [page:Quaternion]
 		</div>
@@ -445,7 +424,7 @@
 		Applies a [page:Quaternion] transform to this vector.
 		</div>
 
-		<h3>[method:Vector3 project]( [page:Camera camera] )</h3>
+		<h3>[method:Vector3 project]( [page:Camera camera] ) [page:Vector3 this]</h3>
 		<div>
 		[page:Camera camera] — camera to use in the projection.<br />
 		</div>
@@ -453,7 +432,7 @@
 		Projects the vector with the camera.
 		</div>
 
-		<h3>[method:Vector3 unproject]( [page:Camera camera] )</h3>
+		<h3>[method:Vector3 unproject]( [page:Camera camera] ) [page:Vector3 this]</h3>
 		<div>
 		[page:Camera camera] — camera to use in the projection.<br />
 		</div>
@@ -461,6 +440,28 @@
 		Unprojects the vector with the camera.
 		</div>
 
+		<h3>[method:Boolean equals]( [page:Vector3 v] ) [page:Vector3 this]</h3>
+		<div>
+		Checks for strict equality of this vector and *v*.
+		</div>
+
+		<h3>[method:Vector3 clone]() [page:Vector3 this]</h3>
+		<div>
+		Clones this vector.
+		</div>
+
+		<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] ) [page:Vector3 this]</h3>
+		<div>
+		array -- An optional array to store the vector to. <br />
+		offset -- An optional offset into the array.
+		</div>
+		<div>
+		Assigns this vector's x value to array[0]. <br />
+		Assigns this vector's y value to array[1]. <br />
+		Assigns this vector's z value to array[2]. <br />
+		Returns the created array.
+		</div>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 67 - 66
docs/api/math/Vector4.html

@@ -43,11 +43,52 @@
 		Sets value of this vector.
 		</div>
 
+		<h3>[method:Vector4 setX]( [page:Float x] ) [page:Vector4 this]</h3>
+		<div>
+		x -- [page:Float]
+		</div>
+		<div>
+		Sets the x component of the vector.
+		</div>
+
+		<h3>[method:Vector4 setY]( [page:Float y] ) [page:Vector4 this]</h3>
+		<div>
+		y -- [page:Float]
+		</div>
+		<div>
+		Sets the y component of the vector.
+		</div>
+
+		<h3>[method:Vector4 setZ]( [page:Float z] ) [page:Vector4 this]</h3>
+		<div>
+		z -- [page:Float]
+		</div>
+		<div>
+		Sets the z component of the vector.
+		</div>
+
+		<h3>[method:Vector4 setW]( [page:Float w] ) [page:Vector4 this]</h3>
+		<div>
+		w -- [page:Float]
+		</div>
+		<div>
+		Sets the w component of the vector.
+		</div>
+
 		<h3>[method:Vector4 copy]( [page:Vector4 v] ) [page:Vector4 this]</h3>
 		<div>
 		Copies value of *v* to this vector.
 		</div>
 
+		<h3>[method:Vector4 fromArray]( [page:Array array] ) [page:Vector4 this]</h3>
+		<div>
+		array -- The source array in the form [x, y, z, w]. <br />
+		offset -- An optional offset into the array.
+		</div>
+		<div>
+		Sets the vector's components based on an array formatted like [x, y, z, w]
+		</div>
+
 		<h3>[method:Vector4 add]( [page:Vector4 v] ) [page:Vector4 this]</h3>
 		<div>
 		Adds *v* to this vector.
@@ -63,7 +104,7 @@
 		Adds the multiple of v and s to this vector.
 		</div>
 
-		<h3>[method:Vector4 sub]( [page:Vector4 v] )</h3>
+		<h3>[method:Vector4 sub]( [page:Vector4 v] ) [page:Vector4 this]</h3>
 		<div>
 		Subtracts *v* from this vector.
 		</div>
@@ -89,17 +130,17 @@
 		Inverts this vector.
 		</div>
 
-		<h3>[method:Float dot]( [page:Vector4 v] )</h3>
+		<h3>[method:Float dot]( [page:Vector4 v] ) [page:Vector4 this]</h3>
 		<div>
 		Computes dot product of this vector and *v*.
 		</div>
 
-		<h3>[method:Float lengthSq]()</h3>
+		<h3>[method:Float lengthSq]() [page:Vector4 this]</h3>
 		<div>
 		Computes squared length of this vector.
 		</div>
 
-		<h3>[method:Float length]()</h3>
+		<h3>[method:Float length]() [page:Vector4 this]</h3>
 		<div>
 		Computes length of this vector.
 		</div>
@@ -124,13 +165,8 @@
 		Sets this vector to be the vector linearly interpolated between *v1* and *v2* with *alpha* factor.
 		</div>
 
-		<h3>[method:Vector4 clone]()</h3>
-		<div>
-		Clones this vector.
-		</div>
 
-
-		<h3>[method:Vector4 clamp]([page:Vector4 min], [page:Vector4 max]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 clamp]( [page:Vector4 min], [page:Vector4 max] ) [page:Vector4 this]</h3>
 		<div>
 		min -- [page:Vector4] <br />
 		max -- [page:Vector4]
@@ -140,7 +176,7 @@
 		If this vector's x, y, z, or w value is less than the min vector's x, y, z, or w value, it is replaced by the corresponding value.
 		</div>
 
-		<h3>[method:Vector4 clampScalar]([page:Float min], [page:Float max]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 clampScalar]( [page:Float min], [page:Float max] ) [page:Vector4 this]</h3>
 		<div>
 		min -- [page:Float] the minimum value the components will be clamped to <br />
 		max -- [page:Float] the maximum value the components will be clamped to
@@ -150,27 +186,27 @@
 		If this vector's x, y, z or w values are less than the min value, they are replaced by the min value.
 		</div>
 
-		<h3>[method:Vector4 floor]()</h3>
+		<h3>[method:Vector4 floor]() [page:Vector4 this]</h3>
 		<div>
 		The components of the vector are rounded downwards (towards negative infinity) to an integer value.
 		</div>
 
-		<h3>[method:Vector4 ceil]()</h3>
+		<h3>[method:Vector4 ceil]() [page:Vector4 this]</h3>
 		<div>
 		The components of the vector are rounded upwards (towards positive infinity) to an integer value.
 		</div>
 
-		<h3>[method:Vector4 round]()</h3>
+		<h3>[method:Vector4 round]() [page:Vector4 this]</h3>
 		<div>
 		The components of the vector are rounded towards the nearest integer value.
 		</div>
 
-		<h3>[method:Vector4 roundToZero]()</h3>
+		<h3>[method:Vector4 roundToZero]() [page:Vector4 this]</h3>
 		<div>
 		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
 		</div>
 
-		<h3>[method:Vector4 applyMatrix4]([page:Matrix4 m]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 applyMatrix4]( [page:Matrix4 m] ) [page:Vector4 this]</h3>
 		<div>
 		m -- [page:Matrix4]
 		</div>
@@ -178,7 +214,7 @@
 		Transforms the vector by the matrix.
 		</div>
 
-		<h3>[method:Vector4 min]([page:Vector4 v]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 min]( [page:Vector4 v] ) [page:Vector4 this]</h3>
 		<div>
 		v -- [page:Vector4]
 		</div>
@@ -186,7 +222,7 @@
 		If this vector's x, y, z, or w value is greater than vector v's x, y, z, or w value, that value is replaced by the corresponding vector v value.
 		</div>
 
-		<h3>[method:Vector4 max]([page:Vector4 v]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 max]( [page:Vector4 v] ) [page:Vector4 this]</h3>
 		<div>
 		v -- [page:Vector4]
 		</div>
@@ -194,7 +230,7 @@
 		If this vector's x, y, z, or w value is less than vector v's x, y, z, or w value, that value is replaced by the corresponding vector v value.
 		</div>
 
-		<h3>[method:Vector4 addScalar]([page:Float s]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 addScalar]( [page:Float s] ) [page:Vector4 this]</h3>
 		<div>
 		s -- [page:Float]
 		</div>
@@ -202,7 +238,7 @@
 		Adds a scalar value to all of the vector's components.
 		</div>
 
-		<h3>[method:Boolean equals]([page:Vector4 v])</h3>
+		<h3>[method:Boolean equals]( [page:Vector4 v] ) [page:Vector4 this]</h3>
 		<div>
 		v -- [page:Vector4]
 		</div>
@@ -210,7 +246,7 @@
 		Checks to see if this vector matches vector v.
 		</div>
 
-		<h3>[method:Vector4 setAxisAngleFromRotationMatrix]([page:Matrix4 m]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 setAxisAngleFromRotationMatrix]( [page:Matrix4 m] ) [page:Vector4 this]</h3>
 		<div>
 		m -- [page:Matrix4]
 		</div>
@@ -220,7 +256,7 @@
 		The axis is stored in components (x, y, z) of the vector, and the rotation in radians is stored in component w
 		</div>
 
-		<h3>[method:Vector4 setAxisAngleFromQuaternion]([page:Quaternion q]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 setAxisAngleFromQuaternion]( [page:Quaternion q] ) [page:Vector4 this]</h3>
 		<div>
 		q -- [page:Quaternion]
 		</div>
@@ -230,7 +266,7 @@
 		The axis is stored in components (x, y, z) of the vector, and the rotation in radians is stored in component w
 		</div>
 
-		<h3>[method:Float getComponent]([page:Integer index])</h3>
+		<h3>[method:Float getComponent]( [page:Integer index] ) [page:Vector4 this]</h3>
 		<div>
 		index -- [page:Integer] 0, 1, 2, or 3
 		</div>
@@ -244,7 +280,7 @@
 
 		</div>
 
-		<h3>[method:null setComponent]([page:Integer index], [page:Float value])</h3>
+		<h3>[method:null setComponent]( [page:Integer index], [page:Float value] ) [page:Vector4 this]</h3>
 		<div>
 		index -- [page:Integer] 0 - 3 <br />
 		value -- [page:Float]
@@ -258,60 +294,25 @@
 		Index 3: w<br/>
 		</div>
 
-		<h3>[method:Vector4 fromArray]([page:Array array]) [page:Vector4 this]</h3>
-		<div>
-		array -- [page:Array] An array formatted [x, y, z, w]
-		</div>
-		<div>
-		Sets the vector's components based on an array formatted like [x, y, z, w]
-		</div>
-
-		<h3>[method:Array toArray]( [page:Array array] )</h3>
-		<div>
-		array -- Optional array to store the vector.
-		</div>
-		<div>
-		Returns an array in the format [x, y, z, w]
-		</div>
-
-		<h3>[method:Float lengthManhattan]()</h3>
+		<h3>[method:Float lengthManhattan]() [page:Vector4 this]</h3>
 		<div>
 		Computes Manhattan length of this vector.<br />
 		[link:http://en.wikipedia.org/wiki/Taxicab_geometry]
 		</div>
 
-
-		<h3>[method:Vector4 setX]([page:Float x]) [page:Vector4 this]</h3>
-		<div>
-		x -- [page:Float]
-		</div>
-		<div>
-		Sets the x component of the vector.
-		</div>
-
-		<h3>[method:Vector4 setY]([page:Float y]) [page:Vector4 this]</h3>
+		<h3>[method:Vector4 clone]() [page:Vector4 this]</h3>
 		<div>
-		y -- [page:Float]
-		</div>
-		<div>
-		Sets the y component of the vector.
+		Clones this vector.
 		</div>
 
-		<h3>[method:Vector4 setZ]([page:Float z]) [page:Vector4 this]</h3>
+		<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] ) [page:Vector4 this]</h3>
 		<div>
-		z -- [page:Float]
+		array -- An optional array to store the vector.
+		offset -- An optional offset into the array.
 		</div>
 		<div>
-		Sets the z component of the vector.
-		</div>
+		Returns an array in the format [x, y, z, w]
 
-		<h3>[method:Vector4 setW]([page:Float w]) [page:Vector4 this]</h3>
-		<div>
-		w -- [page:Float]
-		</div>
-		<div>
-		Sets the w component of the vector.
-		</div>
 
 		<h2>Source</h2>
 

+ 20 - 20
src/math/Matrix3.js

@@ -235,21 +235,10 @@ THREE.Matrix3.prototype = {
 
 	flattenToArrayOffset: function ( array, offset ) {
 
-		var te = this.elements;
-
-		array[ offset ] = te[ 0 ];
-		array[ offset + 1 ] = te[ 1 ];
-		array[ offset + 2 ] = te[ 2 ];
-
-		array[ offset + 3 ] = te[ 3 ];
-		array[ offset + 4 ] = te[ 4 ];
-		array[ offset + 5 ] = te[ 5 ];
+		console.warn( "THREE.Matrix3: .flattenToArrayOffset is deprecated " +
+				"- just use .toArray instead." );
 
-		array[ offset + 6 ] = te[ 6 ];
-		array[ offset + 7 ] = te[ 7 ];
-		array[ offset + 8 ]  = te[ 8 ];
-
-		return array;
+		return this.toArray( array, offset );
 
 	},
 
@@ -285,15 +274,26 @@ THREE.Matrix3.prototype = {
 
 	},
 
-	toArray: function () {
+	toArray: function ( array, offset ) {
+
+		if ( array === undefined ) array = [];
+		if ( offset === undefined ) offset = 0;
 
 		var te = this.elements;
 
-		return [
-			te[ 0 ], te[ 1 ], te[ 2 ],
-			te[ 3 ], te[ 4 ], te[ 5 ],
-			te[ 6 ], te[ 7 ], te[ 8 ]
-		];
+		array[ offset ] = te[ 0 ];
+		array[ offset + 1 ] = te[ 1 ];
+		array[ offset + 2 ] = te[ 2 ];
+
+		array[ offset + 3 ] = te[ 3 ];
+		array[ offset + 4 ] = te[ 4 ];
+		array[ offset + 5 ] = te[ 5 ];
+
+		array[ offset + 6 ] = te[ 6 ];
+		array[ offset + 7 ] = te[ 7 ];
+		array[ offset + 8 ]  = te[ 8 ];
+
+		return array;
 
 	}
 

+ 28 - 29
src/math/Matrix4.js

@@ -560,29 +560,10 @@ THREE.Matrix4.prototype = {
 
 	flattenToArrayOffset: function ( array, offset ) {
 
-		var te = this.elements;
-
-		array[ offset ] = te[ 0 ];
-		array[ offset + 1 ] = te[ 1 ];
-		array[ offset + 2 ] = te[ 2 ];
-		array[ offset + 3 ] = te[ 3 ];
-
-		array[ offset + 4 ] = te[ 4 ];
-		array[ offset + 5 ] = te[ 5 ];
-		array[ offset + 6 ] = te[ 6 ];
-		array[ offset + 7 ] = te[ 7 ];
+		console.warn( "THREE.Matrix3: .flattenToArrayOffset is deprecated " +
+				"- just use .toArray instead." );
 
-		array[ offset + 8 ]  = te[ 8 ];
-		array[ offset + 9 ]  = te[ 9 ];
-		array[ offset + 10 ] = te[ 10 ];
-		array[ offset + 11 ] = te[ 11 ];
-
-		array[ offset + 12 ] = te[ 12 ];
-		array[ offset + 13 ] = te[ 13 ];
-		array[ offset + 14 ] = te[ 14 ];
-		array[ offset + 15 ] = te[ 15 ];
-
-		return array;
+		return this.toArray( array, offset );
 
 	},
 
@@ -946,16 +927,34 @@ THREE.Matrix4.prototype = {
 
 	},
 
-	toArray: function () {
+	toArray: function ( array, offset ) {
+
+		if ( array === undefined ) array = [];
+		if ( offset === undefined ) offset = 0;
 
 		var te = this.elements;
 
-		return [
-			te[ 0 ], te[ 1 ], te[ 2 ], te[ 3 ],
-			te[ 4 ], te[ 5 ], te[ 6 ], te[ 7 ],
-			te[ 8 ], te[ 9 ], te[ 10 ], te[ 11 ],
-			te[ 12 ], te[ 13 ], te[ 14 ], te[ 15 ]
-		];
+		array[ offset ] = te[ 0 ];
+		array[ offset + 1 ] = te[ 1 ];
+		array[ offset + 2 ] = te[ 2 ];
+		array[ offset + 3 ] = te[ 3 ];
+
+		array[ offset + 4 ] = te[ 4 ];
+		array[ offset + 5 ] = te[ 5 ];
+		array[ offset + 6 ] = te[ 6 ];
+		array[ offset + 7 ] = te[ 7 ];
+
+		array[ offset + 8 ]  = te[ 8 ];
+		array[ offset + 9 ]  = te[ 9 ];
+		array[ offset + 10 ] = te[ 10 ];
+		array[ offset + 11 ] = te[ 11 ];
+
+		array[ offset + 12 ] = te[ 12 ];
+		array[ offset + 13 ] = te[ 13 ];
+		array[ offset + 14 ] = te[ 14 ];
+		array[ offset + 15 ] = te[ 15 ];
+
+		return array;
 
 	}
 

+ 1 - 1
src/objects/Skeleton.js

@@ -155,7 +155,7 @@ THREE.Skeleton.prototype.update = ( function () {
 			var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;
 
 			offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );
-			offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
+			offsetMatrix.toArray( this.boneMatrices, b * 16 );
 
 		}
 

+ 98 - 502
src/renderers/WebGLRenderer.js

@@ -824,13 +824,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			}
 
-			var uniforms = program.getUniforms();
-
-			if ( uniforms.morphTargetInfluences !== null ) {
-
-				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );
-
-			}
+			program.getUniforms().setValue(
+					_gl, 'morphTargetInfluences', morphInfluences );
 
 			updateBuffers = true;
 
@@ -1631,22 +1626,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		var uniformLocations = materialProperties.program.getUniforms();
-
-		materialProperties.uniformsList = [];
-
-		for ( var u in uniforms ) {
-
-			var location = uniformLocations[ u ];
-
-			if ( location ) {
-
-				materialProperties.uniformsList.push( [ materialProperties.__webglShader.uniforms[ u ], location ] );
-
-			}
-
-		}
-
 		if ( material instanceof THREE.MeshPhongMaterial ||
 				material instanceof THREE.MeshLambertMaterial ||
 				material instanceof THREE.MeshStandardMaterial ||
@@ -1673,22 +1652,13 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		// detect dynamic uniforms
-
-		materialProperties.hasDynamicUniforms = false;
+		var progUniforms = materialProperties.program.getUniforms(),
+			uniformsList =
+					THREE.WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
 
-		for ( var j = 0, jl = materialProperties.uniformsList.length; j < jl; j ++ ) {
-
-			var uniform = materialProperties.uniformsList[ j ][ 0 ];
-
-			if ( uniform.dynamic === true ) {
-
-				materialProperties.hasDynamicUniforms = true;
-				break;
-
-			}
-
-		}
+		materialProperties.uniformsList = uniformsList;
+		materialProperties.dynamicUniforms =
+				THREE.WebGLUniforms.splitDynamic( uniformsList, uniforms );
 
 	}
 
@@ -1802,11 +1772,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		if ( refreshProgram || camera !== _currentCamera ) {
 
-			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
+			p_uniforms.set( _gl, camera, 'projectionMatrix' );
 
 			if ( capabilities.logarithmicDepthBuffer ) {
 
-				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
+				p_uniforms.setValue( _gl, 'logDepthBufFC',
+						2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
 
 			}
 
@@ -1832,10 +1803,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 				 material instanceof THREE.MeshStandardMaterial ||
 				 material.envMap ) {
 
-				if ( p_uniforms.cameraPosition !== undefined ) {
+				var uCamPos = p_uniforms.map.cameraPosition;
+
+				if ( uCamPos !== undefined ) {
 
-					_vector3.setFromMatrixPosition( camera.matrixWorld );
-					_gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z );
+					uCamPos.setValue( _gl,
+							_vector3.setFromMatrixPosition( camera.matrixWorld ) );
 
 				}
 
@@ -1848,26 +1821,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 				 material instanceof THREE.ShaderMaterial ||
 				 material.skinning ) {
 
-				if ( p_uniforms.viewMatrix !== undefined ) {
-
-					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements );
-
-				}
+				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
 
 			}
 
-
-			if ( p_uniforms.toneMappingExposure !== undefined ) {
-
-				_gl.uniform1f( p_uniforms.toneMappingExposure, _this.toneMappingExposure );
-
-			}
-
-			if ( p_uniforms.toneMappingWhitePoint !== undefined ) {
-
-				_gl.uniform1f( p_uniforms.toneMappingWhitePoint, _this.toneMappingWhitePoint );
-
-			}
+			p_uniforms.set( _gl, _this, 'toneMappingExposure' );
+			p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );
 
 		}
 
@@ -1877,46 +1836,22 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		if ( material.skinning ) {
 
-			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
+			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
+			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
 
-				_gl.uniformMatrix4fv( p_uniforms.bindMatrix, false, object.bindMatrix.elements );
+			var skeleton = object.skeleton;
 
-			}
-
-			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
-
-				_gl.uniformMatrix4fv( p_uniforms.bindMatrixInverse, false, object.bindMatrixInverse.elements );
-
-			}
+			if ( skeleton ) {
 
-			if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) {
+				if ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {
 
-				if ( p_uniforms.boneTexture !== undefined ) {
+					p_uniforms.set( _gl, skeleton, 'boneTexture' );
+					p_uniforms.set( _gl, skeleton, 'boneTextureWidth' );
+					p_uniforms.set( _gl, skeleton, 'boneTextureHeight' );
 
-					var textureUnit = getTextureUnit();
-
-					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
-					_this.setTexture( object.skeleton.boneTexture, textureUnit );
-
-				}
-
-				if ( p_uniforms.boneTextureWidth !== undefined ) {
-
-					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
-
-				}
-
-				if ( p_uniforms.boneTextureHeight !== undefined ) {
-
-					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
-
-				}
-
-			} else if ( object.skeleton && object.skeleton.boneMatrices ) {
-
-				if ( p_uniforms.boneGlobalMatrices !== undefined ) {
+				} else {
 
-					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
+					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
 
 				}
 
@@ -2010,49 +1945,33 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			}
 
-			// load common uniforms
-
-			loadUniformsGeneric( materialProperties.uniformsList );
-
-		}
-
-		loadUniformsMatrices( p_uniforms, object );
-
-		if ( p_uniforms.modelMatrix !== undefined ) {
-
-			_gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
-
-		}
-
-		if ( materialProperties.hasDynamicUniforms === true ) {
-
-			updateDynamicUniforms( materialProperties.uniformsList, object, camera );
+			THREE.WebGLUniforms.upload(
+					_gl, materialProperties.uniformsList, m_uniforms, _this );
 
 		}
 
-		return program;
 
-	}
+		// common matrices
 
-	function updateDynamicUniforms ( uniforms, object, camera ) {
+		p_uniforms.set( _gl, object, 'modelViewMatrix' );
+		p_uniforms.set( _gl, object, 'normalMatrix' );
+		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
 
-		var dynamicUniforms = [];
 
-		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {
+		// dynamic uniforms
 
-			var uniform = uniforms[ j ][ 0 ];
-			var onUpdateCallback = uniform.onUpdateCallback;
+		var dynUniforms = materialProperties.dynamicUniforms;
 
-			if ( onUpdateCallback !== undefined ) {
+		if ( dynUniforms !== null ) {
 
-				onUpdateCallback.bind( uniform )( object, camera );
-				dynamicUniforms.push( uniforms[ j ] );
+			THREE.WebGLUniforms.evalDynamic(
+					dynUniforms, m_uniforms, object, camera );
 
-			}
+			THREE.WebGLUniforms.upload( _gl, dynUniforms, m_uniforms, _this );
 
 		}
 
-		loadUniformsGeneric( dynamicUniforms );
+		return program;
 
 	}
 
@@ -2343,384 +2262,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
-	// Uniforms (load to GPU)
-
-	function loadUniformsMatrices ( uniforms, object ) {
-
-		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
-
-		if ( uniforms.normalMatrix ) {
-
-			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
-
-		}
-
-	}
-
-	function getTextureUnit() {
-
-		var textureUnit = _usedTextureUnits;
-
-		if ( textureUnit >= capabilities.maxTextures ) {
-
-			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
-
-		}
-
-		_usedTextureUnits += 1;
-
-		return textureUnit;
-
-	}
-
-	function loadUniform( uniform, type, location, value ) {
-
-		var texture, textureUnit;
-
-		if ( type === '1i' ) {
-
-			_gl.uniform1i( location, value );
-
-		} else if ( type === '1f' ) {
-
-			_gl.uniform1f( location, value );
-
-		} else if ( type === '2f' ) {
-
-			_gl.uniform2f( location, value[ 0 ], value[ 1 ] );
-
-		} else if ( type === '3f' ) {
-
-			_gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] );
-
-		} else if ( type === '4f' ) {
-
-			_gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] );
-
-		} else if ( type === '1iv' ) {
-
-			_gl.uniform1iv( location, value );
-
-		} else if ( type === '3iv' ) {
-
-			_gl.uniform3iv( location, value );
-
-		} else if ( type === '1fv' ) {
-
-			_gl.uniform1fv( location, value );
-
-		} else if ( type === '2fv' ) {
-
-			_gl.uniform2fv( location, value );
-
-		} else if ( type === '3fv' ) {
-
-			_gl.uniform3fv( location, value );
-
-		} else if ( type === '4fv' ) {
-
-			_gl.uniform4fv( location, value );
-
-		} else if ( type === 'Matrix2fv' ) {
-
-			_gl.uniformMatrix2fv( location, false, value );
-
-		} else if ( type === 'Matrix3fv' ) {
-
-			_gl.uniformMatrix3fv( location, false, value );
-
-		} else if ( type === 'Matrix4fv' ) {
-
-			_gl.uniformMatrix4fv( location, false, value );
-
-		//
-
-		} else if ( type === 'i' ) {
-
-			// console.warn( 'THREE.WebGLRenderer: Uniform "i" is now "1i".' );
-			_gl.uniform1i( location, value );
-
-		} else if ( type === 'f' ) {
-
-			// console.warn( 'THREE.WebGLRenderer: Uniform "f" is now "1f".' );
-			_gl.uniform1f( location, value );
-
-		} else if ( type === 'iv1' ) {
-
-			// console.warn( 'THREE.WebGLRenderer: Uniform "iv1" is now "1iv".' );
-			_gl.uniform1iv( location, value );
-
-		} else if ( type === 'iv' ) {
-
-			// console.warn( 'THREE.WebGLRenderer: Uniform "iv" is now "3iv".' );
-			_gl.uniform3iv( location, value );
-
-		} else if ( type === 'fv1' ) {
-
-			// console.warn( 'THREE.WebGLRenderer: Uniform "fv1" is now "1fv".' );
-			_gl.uniform1fv( location, value );
-
-		} else if ( type === 'fv' ) {
-
-			// console.warn( 'THREE.WebGLRenderer: Uniform "fv" is now "3fv".' );
-			_gl.uniform3fv( location, value );
-
-		} else if ( type === 'v2' ) {
-
-			// single THREE.Vector2
-			_gl.uniform2f( location, value.x, value.y );
-
-		} else if ( type === 'v3' ) {
-
-			// single THREE.Vector3
-			_gl.uniform3f( location, value.x, value.y, value.z );
-
-		} else if ( type === 'v4' ) {
-
-			// single THREE.Vector4
-			_gl.uniform4f( location, value.x, value.y, value.z, value.w );
-
-		} else if ( type === 'c' ) {
-
-			// single THREE.Color
-			_gl.uniform3f( location, value.r, value.g, value.b );
-
-		} else if ( type === 's' || type === 'sa' ) {
-
-			var properties = uniform.properties,
-				identifiers = location.ids,
-				nestedInfos = location.infos;
-
-			for ( var i = 0, n = identifiers.length; i !== n; ++ i ) {
-
-				var id = identifiers[ i ],
-					isArray = typeof id === 'number',
-					nestedUniform = isArray ? uniform : properties[ id ],
-					nestedInfo = nestedInfos[ i ],
-					nestedType = nestedInfo.infos !== undefined ? 's' : nestedUniform.type,
-					nestedValue = value[ id ];
-
-				loadUniform( nestedUniform, nestedType, nestedInfo, nestedValue );
-
-			}
-
-		} else if ( type === 'v2v' ) {
-
-			// array of THREE.Vector2
-
-			if ( uniform._array === undefined ) {
-
-				uniform._array = new Float32Array( 2 * value.length );
-
-			}
-
-			for ( var i = 0, i2 = 0, il = value.length; i < il; i ++, i2 += 2 ) {
-
-				uniform._array[ i2 + 0 ] = value[ i ].x;
-				uniform._array[ i2 + 1 ] = value[ i ].y;
-
-			}
-
-			_gl.uniform2fv( location, uniform._array );
-
-		} else if ( type === 'v3v' ) {
-
-			// array of THREE.Vector3
-
-			if ( uniform._array === undefined ) {
-
-				uniform._array = new Float32Array( 3 * value.length );
-
-			}
-
-			for ( var i = 0, i3 = 0, il = value.length; i < il; i ++, i3 += 3 ) {
-
-				uniform._array[ i3 + 0 ] = value[ i ].x;
-				uniform._array[ i3 + 1 ] = value[ i ].y;
-				uniform._array[ i3 + 2 ] = value[ i ].z;
-
-			}
-
-			_gl.uniform3fv( location, uniform._array );
-
-		} else if ( type === 'v4v' ) {
-
-			// array of THREE.Vector4
-
-			if ( uniform._array === undefined ) {
-
-				uniform._array = new Float32Array( 4 * value.length );
-
-			}
-
-			for ( var i = 0, i4 = 0, il = value.length; i < il; i ++, i4 += 4 ) {
-
-				uniform._array[ i4 + 0 ] = value[ i ].x;
-				uniform._array[ i4 + 1 ] = value[ i ].y;
-				uniform._array[ i4 + 2 ] = value[ i ].z;
-				uniform._array[ i4 + 3 ] = value[ i ].w;
-
-			}
-
-			_gl.uniform4fv( location, uniform._array );
-
-		} else if ( type === 'm2' ) {
-
-			// single THREE.Matrix2
-			_gl.uniformMatrix2fv( location, false, value.elements );
-
-		} else if ( type === 'm3' ) {
-
-			// single THREE.Matrix3
-			_gl.uniformMatrix3fv( location, false, value.elements );
-
-		} else if ( type === 'm3v' ) {
-
-			// array of THREE.Matrix3
-
-			if ( uniform._array === undefined ) {
-
-				uniform._array = new Float32Array( 9 * value.length );
-
-			}
-
-			for ( var i = 0, il = value.length; i < il; i ++ ) {
-
-				value[ i ].flattenToArrayOffset( uniform._array, i * 9 );
-
-			}
-
-			_gl.uniformMatrix3fv( location, false, uniform._array );
-
-		} else if ( type === 'm4' ) {
-
-			// single THREE.Matrix4
-			_gl.uniformMatrix4fv( location, false, value.elements );
-
-		} else if ( type === 'm4v' ) {
-
-			// array of THREE.Matrix4
-
-			if ( uniform._array === undefined ) {
-
-				uniform._array = new Float32Array( 16 * value.length );
-
-			}
-
-			for ( var i = 0, il = value.length; i < il; i ++ ) {
-
-				value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
-
-			}
-
-			_gl.uniformMatrix4fv( location, false, uniform._array );
-
-		} else if ( type === 't' ) {
-
-			// single THREE.Texture (2d or cube)
-
-			texture = value;
-			textureUnit = getTextureUnit();
-
-			_gl.uniform1i( location, textureUnit );
-
-			if ( ! texture ) return;
-
-			if ( texture instanceof THREE.CubeTexture ||
-				 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
-
-				// CompressedTexture can have Array in image :/
-
-				setCubeTexture( texture, textureUnit );
-
-			} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
-
-				setCubeTextureDynamic( texture.texture, textureUnit );
-
-			} else if ( texture instanceof THREE.WebGLRenderTarget ) {
-
-				_this.setTexture( texture.texture, textureUnit );
-
-			} else {
-
-				_this.setTexture( texture, textureUnit );
-
-			}
-
-		} else if ( type === 'tv' ) {
-
-			// array of THREE.Texture (2d or cube)
-
-			if ( uniform._array === undefined ) {
-
-				uniform._array = [];
-
-			}
-
-			for ( var i = 0, il = uniform.value.length; i < il; i ++ ) {
-
-				uniform._array[ i ] = getTextureUnit();
-
-			}
-
-			_gl.uniform1iv( location, uniform._array );
-
-			for ( var i = 0, il = uniform.value.length; i < il; i ++ ) {
-
-				texture = uniform.value[ i ];
-				textureUnit = uniform._array[ i ];
-
-				if ( ! texture ) continue;
-
-				if ( texture instanceof THREE.CubeTexture ||
-					 ( texture.image instanceof Array && texture.image.length === 6 ) ) {
-
-					// CompressedTexture can have Array in image :/
-
-					setCubeTexture( texture, textureUnit );
-
-				} else if ( texture instanceof THREE.WebGLRenderTarget ) {
-
-					_this.setTexture( texture.texture, textureUnit );
-
-				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
-
-					setCubeTextureDynamic( texture.texture, textureUnit );
-
-				} else {
-
-					_this.setTexture( texture, textureUnit );
-
-				}
-
-			}
-
-		} else {
-
-			console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
-
-		}
-
-	}
-
-	function loadUniformsGeneric( uniforms ) {
-
-		for ( var i = 0, l = uniforms.length; i < l; i ++ ) {
-
-			var uniform = uniforms[ i ][ 0 ];
-
-			// needsUpdate property is not added to all uniforms.
-			if ( uniform.needsUpdate === false ) continue;
-
-			var type = uniform.type;
-			var location = uniforms[ i ][ 1 ];
-			var value = uniform.value;
-
-			loadUniform( uniform, type, location, value );
-
-		}
-
-	}
+	// Lighting
 
 	function setupShadows ( lights ) {
 
@@ -2894,6 +2436,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
+	// Clipping
 
 	function setupGlobalClippingPlanes( planes, camera ) {
 
@@ -3053,6 +2596,22 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	// Textures
 
+	function allocTextureUnit() {
+
+		var textureUnit = _usedTextureUnits;
+
+		if ( textureUnit >= capabilities.maxTextures ) {
+
+			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
+
+		}
+
+		_usedTextureUnits += 1;
+
+		return textureUnit;
+
+	}
+
 	function setTextureParameters ( textureType, texture, isPowerOfTwoImage ) {
 
 		var extension;
@@ -3246,7 +2805,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
-	this.setTexture = function ( texture, slot ) {
+	function setTexture2D( texture, slot ) {
+
+		if ( texture instanceof THREE.WebGLRenderTarget ) texture = texture.texture;
 
 		var textureProperties = properties.get( texture );
 
@@ -3464,6 +3025,41 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
+	var setTextureWarned = false;
+	this.setTexture = function( texture, slot ) {
+
+		if ( ! setTextureWarned ) {
+
+			console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, " +
+				"use setTexture2D instead." );
+			setTextureWarned = true;
+
+		}
+
+		setTexture2D( texture, slot );
+
+	};
+
+	this.allocTextureUnit = allocTextureUnit;
+	this.setTexture2D = setTexture2D;
+	this.setTextureCube = function( texture, slot ) {
+
+		if ( texture instanceof THREE.CubeTexture ||
+			 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
+
+			// CompressedTexture can have Array in image :/
+
+			setCubeTexture( texture, slot );
+
+		} else {
+			// assumed: texture instanceof THREE.WebGLRenderTargetCube
+
+			setCubeTextureDynamic( texture.texture, slot );
+
+		}
+
+	};
+
 	// Render targets
 
 	// Setup storage for target texture and bind it to correct framebuffer

+ 2 - 2
src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl

@@ -33,11 +33,11 @@
 
 	#else
 
-		uniform mat4 boneGlobalMatrices[ MAX_BONES ];
+		uniform mat4 boneMatrices[ MAX_BONES ];
 
 		mat4 getBoneMatrix( const in float i ) {
 
-			mat4 bone = boneGlobalMatrices[ int(i) ];
+			mat4 bone = boneMatrices[ int(i) ];
 			return bone;
 
 		}

+ 2 - 107
src/renderers/webgl/WebGLProgram.js

@@ -105,112 +105,6 @@ THREE.WebGLProgram = ( function () {
 
 	}
 
-
-	var ReNamePart = /([\w\d_]+)(\])?(\[|\.)?/g;
-
-	function attachUniformInfo( name, info, root ) {
-		// attaches 'info' at the right spot according to parsed name
-
-		var ctx = root,
-			len = name.length;
-
-		for (; ;) {
-
-			var ids = ctx.ids,
-				infos = ctx.infos,
-
-				match = ReNamePart.exec( name ),
-				matchEnd = ReNamePart.lastIndex,
-
-				id = match[ 1 ],
-				idIsIndex = match[ 2 ] === ']',
-				subscript = match[ 3 ];
-
-			if ( idIsIndex ) id = + id; // avoid parsing strings in renderer
-
-			if ( subscript === undefined ||
-					subscript === '[' && matchEnd + 2 === len ) {
-				// bare name or pure bottom-level array with "[0]" suffix
-
-				if ( ctx === root ) {
-
-					ctx[ id ] = info;
-
-				} else {
-
-					ids.push( id );
-					infos.push( info );
-
-				}
-
-				break;
-
-			} else {
-				// step into context and create it in case it doesn't exist
-
-				if ( ctx === root ) {
-
-					var nextCtx = ctx[ id ];
-
-					if ( nextCtx === undefined ) {
-
-						nextCtx = { ids: [], infos: [] };
-						ctx[ id ] = nextCtx;
-
-					}
-
-					ctx = nextCtx;
-
-				} else {
-
-					var i = ids.indexOf( id );
-
-					if ( i === -1 ) {
-
-						i = ids.length;
-
-						ids.push( id );
-						infos.push( { ids: [], infos: [] } );
-
-					}
-
-					ctx = ctx.infos[ i ];
-
-				}
-
-			}
-
-		}
-
-		// reset stateful RegExp object, because of early exit
-		ReNamePart.lastIndex = 0;
-
-	}
-
-
-	function fetchUniformLocations( gl, program, identifiers ) {
-
-		var uniforms = {};
-
-		var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
-
-		for ( var i = 0; i !== n; ++ i ) {
-
-			var info = gl.getActiveUniform( program, i ),
-				name = info.name,
-
-				location = gl.getUniformLocation( program, name );
-
-			// console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name);
-
-			attachUniformInfo( name, location, uniforms );
-
-		}
-
-		return uniforms;
-
-	}
-
 	function fetchAttributeLocations( gl, program, identifiers ) {
 
 		var attributes = {};
@@ -676,7 +570,8 @@ THREE.WebGLProgram = ( function () {
 
 			if ( cachedUniforms === undefined ) {
 
-				cachedUniforms = fetchUniformLocations( gl, program );
+				cachedUniforms =
+						new THREE.WebGLUniforms( gl, program, renderer );
 
 			}
 

+ 607 - 0
src/renderers/webgl/WebGLUniforms.js

@@ -0,0 +1,607 @@
+/**
+ *
+ * Uniforms of a program.
+ * Those form a tree structure with a special top-level container for the root,
+ * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.
+ *
+ *
+ * Properties of inner nodes including the top-level container:
+ *
+ * .seq - array of nested uniforms
+ * .map - nested uniforms by name
+ *
+ *
+ * Methods of all nodes except the top-level container:
+ *
+ * .setValue( gl, value, [renderer] )
+ *
+ * 		uploads a uniform value(s)
+ *  	the 'renderer' parameter is needed for sampler uniforms
+ *
+ *
+ * Static methods of the top-level container (renderer factorizations):
+ *
+ * .upload( gl, seq, values, renderer )
+ *
+ * 		sets uniforms in 'seq' to 'values[id].value'
+ *
+ * .seqWithValue( seq, values ) : filteredSeq
+ *
+ * 		filters 'seq' entries with corresponding entry in values
+ *
+ * .splitDynamic( seq, values ) : filteredSeq
+ *
+ * 		filters 'seq' entries with dynamic entry and removes them from 'seq'
+ *
+ *
+ * Methods of the top-level container (renderer factorizations):
+ *
+ * .setValue( gl, name, value )
+ *
+ * 		sets uniform with  name 'name' to 'value'
+ *
+ * .set( gl, obj, prop )
+ *
+ * 		sets uniform from object and property with same name than uniform
+ *
+ * .setOptional( gl, obj, prop )
+ *
+ * 		like .set for an optional property of the object
+ *
+ *
+ * @author tschw
+ *
+ */
+
+THREE.WebGLUniforms = ( function() { // scope
+
+	// --- Base for inner nodes (including the root) ---
+
+	var UniformContainer = function() {
+
+			this.seq = [];
+			this.map = {};
+
+		},
+
+	// --- Utilities ---
+
+	// Array Cache (provides arrays for temporary use by type and size)
+
+		arrayCaches = [],
+		arrayCacheTypes = [],
+
+		allocTemporaryArray = function( type, size ) {
+
+			var typeIndex = arrayCacheTypes.indexOf( type );
+
+			if ( typeIndex === - 1 ) {
+
+				typeIndex = arrayCacheTypes.length;
+				arrayCacheTypes.push( type );
+				arrayCaches.push( [] );
+
+			}
+
+			var arrayCache = arrayCaches[ typeIndex ],
+				cachedArray = arrayCache[ size ];
+
+			if ( cachedArray === undefined ) {
+
+				cachedArray = new type( size );
+				arrayCache[ size ] = cachedArray;
+
+			}
+
+			return cachedArray;
+
+		},
+
+		uncacheTemporaryArrays = function() {
+
+			arrayCaches.length = 0;
+			arrayCacheTypes.length = 0;
+
+		},
+
+	// Flattening for arrays of vectors and matrices
+
+		flatten = function( array, stride ) {
+
+			var n = array.length,
+				r = allocTemporaryArray( Float32Array, n * stride );
+
+			for ( var i = 0, offset = 0; i !== n; ++ i, offset += stride ) {
+
+				array[ i ].toArray( r, offset );
+
+			}
+
+			return r;
+
+		},
+
+	// Texture unit allocation
+
+		allocTexUnits = function( renderer, n ) {
+
+			var r = allocTemporaryArray( Int32Array, n );
+
+			for ( var i = 0; i !== n; ++ i )
+				r[ i ] = renderer.allocTextureUnit();
+
+			return r;
+
+		},
+
+	// --- Setters ---
+
+	// Note: Defining these methods externally, because they come in a bunch
+	// and this way their names minify.
+
+		// Single scalar
+
+		setValue1f = function( gl, v ) { gl.uniform1f( this.addr, v ); },
+		setValue1i = function( gl, v ) { gl.uniform1i( this.addr, v ); },
+
+		// Single float vector (from flat array or THREE.VectorN)
+
+		setValue2fv = function( gl, v ) {
+
+			if ( v.x === undefined ) gl.uniform2fv( this.addr, v );
+			else gl.uniform2f( this.addr, v.x, v.y );
+
+		},
+
+		setValue3fv = function( gl, v ) {
+
+			if ( v.x !== undefined )
+				gl.uniform3f( this.addr, v.x, v.y, v.z );
+			else if ( v.r !== undefined )
+				gl.uniform3f( this.addr, v.r, v.g, v.b );
+			else
+				gl.uniform3fv( this.addr, v );
+
+		},
+
+		setValue4fv = function( gl, v ) {
+
+			if ( v.x === undefined ) gl.uniform4fv( this.addr, v );
+			else gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
+
+		},
+
+		// Single matrix (from flat array or MatrixN)
+
+		setValue2fm = function( gl, v ) {
+
+			gl.uniformMatrix2fv( this.addr, false, v.elements || v );
+
+		},
+
+		setValue3fm = function( gl, v ) {
+
+			gl.uniformMatrix3fv( this.addr, false, v.elements || v );
+
+		},
+
+		setValue4fm = function( gl, v ) {
+
+			gl.uniformMatrix4fv( this.addr, false, v.elements || v );
+
+		},
+
+		// Single texture (2D / Cube)
+
+		setValueT1 = function( gl, v, renderer ) {
+
+			var unit = renderer.allocTextureUnit();
+			gl.uniform1i( this.addr, unit );
+			if ( v ) renderer.setTexture2D( v, unit );
+
+		},
+
+		setValueT6 = function( gl, v, renderer ) {
+
+			var unit = renderer.allocTextureUnit();
+			gl.uniform1i( this.addr, unit );
+			if ( v ) renderer.setTextureCube( v, unit );
+
+		},
+
+		// Integer / Boolean vectors or arrays thereof (always flat arrays)
+
+		setValue2iv = function( gl, v ) { gl.uniform2iv( this.addr, v ); },
+		setValue3iv = function( gl, v ) { gl.uniform3iv( this.addr, v ); },
+		setValue4iv = function( gl, v ) { gl.uniform4iv( this.addr, v ); },
+
+		// Helper to pick the right setter for the singular case
+
+		getSingularSetter = function( type ) {
+
+			switch ( type ) {
+
+				case 0x1406: return setValue1f; // FLOAT
+				case 0x8b50: return setValue2fv; // _VEC2
+				case 0x8b51: return setValue3fv; // _VEC3
+				case 0x8b52: return setValue4fv; // _VEC4
+
+				case 0x8b5a: return setValue2fm; // _MAT2
+				case 0x8b5b: return setValue3fm; // _MAT3
+				case 0x8b5c: return setValue4fm; // _MAT4
+
+				case 0x8b5e: return setValueT1; // SAMPLER_2D
+				case 0x8b60: return setValueT6; // SAMPLER_CUBE
+
+				case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
+				case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
+				case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
+				case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
+
+			}
+
+		},
+
+		// Array of scalars
+
+		setValue1fv = function( gl, v ) { gl.uniform1fv( this.addr, v ); },
+		setValue1iv = function( gl, v ) { gl.uniform1iv( this.addr, v ); },
+
+		// Array of vectors (flat or from THREE classes)
+
+		setValueV2a = function( gl, v ) {
+
+			if ( v.length === this.size ) v = flatten( v, 2 );
+			gl.uniform2fv( this.addr, v );
+
+		},
+
+		setValueV3a = function( gl, v ) {
+
+			if ( v.length === this.size ) v = flatten( v, 3 );
+			gl.uniform3fv( this.addr, v );
+
+		},
+
+		setValueV4a = function( gl, v ) {
+
+			if ( v.length === this.size ) v = flatten( v, 4 );
+			gl.uniform4fv( this.addr, v );
+
+		},
+
+		// Array of matrices (flat or from THREE clases)
+
+		setValueM2a = function( gl, v ) {
+
+			if ( v.length === this.size ) v = flatten( v, 4 );
+			gl.uniformMatrix2fv( this.addr, false, v );
+
+		},
+
+		setValueM3a = function( gl, v ) {
+
+			if ( v.length === this.size ) v = flatten( v, 9 );
+			gl.uniformMatrix3fv( this.addr, false, v );
+
+		},
+
+		setValueM4a = function( gl, v ) {
+
+			if ( v.length === this.size ) v = flatten( v, 16 );
+			gl.uniformMatrix4fv( this.addr, false, v );
+
+		},
+
+		// Array of textures (2D / Cube)
+
+		setValueT1a = function( gl, v, renderer ) {
+
+			var n = v.length,
+				units = allocTexUnits( renderer, n );
+
+			gl.uniform1iv( this.addr, units );
+
+			for ( var i = 0; i !== n; ++ i ) {
+
+				var tex = v[ i ];
+				if ( tex ) renderer.setTexture2D( tex, units[ i ] );
+
+			}
+
+		},
+
+		setValueT6a = function( gl, v, renderer ) {
+
+			var n = v.length,
+				units = allocTexUnits( renderer, n );
+
+			gl.uniform1iv( this.addr, units );
+
+			for ( var i = 0; i !== n; ++ i ) {
+
+				var tex = v[ i ];
+				if ( tex ) renderer.setTextureCube( tex, units[ i ] );
+
+			}
+
+		},
+
+
+		// Helper to pick the right setter for a pure (bottom-level) array
+
+		getPureArraySetter = function( type ) {
+
+			switch ( type ) {
+
+				case 0x1406: return setValue1fv; // FLOAT
+				case 0x8b50: return setValueV2a; // _VEC2
+				case 0x8b51: return setValueV3a; // _VEC3
+				case 0x8b52: return setValueV4a; // _VEC4
+
+				case 0x8b5a: return setValueM2a; // _MAT2
+				case 0x8b5b: return setValueM3a; // _MAT3
+				case 0x8b5c: return setValueM4a; // _MAT4
+
+				case 0x8b5e: return setValueT1a; // SAMPLER_2D
+				case 0x8b60: return setValueT6a; // SAMPLER_CUBE
+
+				case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL
+				case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
+				case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
+				case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
+
+			}
+
+		},
+
+	// --- Uniform Classes ---
+
+		SingleUniform = function SingleUniform( id, activeInfo, addr ) {
+
+			this.id = id;
+			this.addr = addr;
+			this.setValue = getSingularSetter( activeInfo.type );
+
+			// this.path = activeInfo.name; // DEBUG
+
+		},
+
+		PureArrayUniform = function( id, activeInfo, addr ) {
+
+			this.id = id;
+			this.addr = addr;
+			this.size = activeInfo.size;
+			this.setValue = getPureArraySetter( activeInfo.type );
+
+			// this.path = activeInfo.name; // DEBUG
+
+		},
+
+		StructuredUniform = function( id ) {
+
+			this.id = id;
+
+			UniformContainer.call( this ); // mix-in
+
+		};
+
+	StructuredUniform.prototype.setValue = function( gl, value ) {
+
+		// Note: Don't need an extra 'renderer' parameter, since samplers
+		// are not allowed in structured uniforms.
+
+		var seq = this.seq;
+
+		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+
+			var u = seq[ i ];
+			u.setValue( gl, value[ u.id ] );
+
+		}
+
+	};
+
+	// --- Top-level ---
+
+	// Parser - builds up the property tree from the path strings
+
+	var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g,
+		// extracts
+		// 	- the identifier (member name or array index)
+		//  - followed by an optional right bracket (found when array index)
+		//  - followed by an optional left bracket or dot (type of subscript)
+		//
+		// Note: These portions can be read in a non-overlapping fashion and
+		// allow straightforward parsing of the hierarchy that WebGL encodes
+		// in the uniform names.
+
+		addUniform = function( container, uniformObject ) {
+
+			container.seq.push( uniformObject );
+			container.map[ uniformObject.id ] = uniformObject;
+
+		},
+
+		parseUniform = function( activeInfo, addr, container ) {
+
+			var path = activeInfo.name,
+				pathLength = path.length;
+
+			// reset RegExp object, because of the early exit of a previous run
+			RePathPart.lastIndex = 0;
+
+			for (; ;) {
+
+				var match = RePathPart.exec( path ),
+					matchEnd = RePathPart.lastIndex,
+
+					id = match[ 1 ],
+					idIsIndex = match[ 2 ] === ']',
+					subscript = match[ 3 ];
+
+				if ( idIsIndex ) id = id | 0; // convert to integer
+
+				if ( subscript === undefined ||
+						subscript === '[' && matchEnd + 2 === pathLength ) {
+					// bare name or "pure" bottom-level array "[0]" suffix
+
+					addUniform( container, subscript === undefined ?
+							new SingleUniform( id, activeInfo, addr ) :
+							new PureArrayUniform( id, activeInfo, addr ) );
+
+					break;
+
+				} else {
+					// step into inner node / create it in case it doesn't exist
+
+					var map = container.map,
+						next = map[ id ];
+
+					if ( next === undefined ) {
+
+						next = new StructuredUniform( id );
+						addUniform( container, next );
+
+					}
+
+					container = next;
+
+				}
+
+			}
+
+		},
+
+	// Root Container
+
+		WebGLUniforms = function WebGLUniforms( gl, program, renderer ) {
+
+			UniformContainer.call( this );
+
+			this.renderer = renderer;
+
+			var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
+
+			for ( var i = 0; i !== n; ++ i ) {
+
+				var info = gl.getActiveUniform( program, i ),
+					path = info.name,
+					addr = gl.getUniformLocation( program, path );
+
+				parseUniform( info, addr, this );
+
+			}
+
+		};
+
+
+	WebGLUniforms.prototype.setValue = function( gl, name, value ) {
+
+		var u = this.map[ name ];
+
+		if ( u !== undefined ) u.setValue( gl, value, this.renderer );
+
+	};
+
+	WebGLUniforms.prototype.set = function( gl, object, name ) {
+
+		var u = this.map[ name ];
+
+		if ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );
+
+	};
+
+	WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
+
+		var v = object[ name ];
+
+		if ( v !== undefined ) this.setValue( gl, name, v );
+
+	};
+
+
+	// Static interface
+
+	WebGLUniforms.upload = function( gl, seq, values, renderer ) {
+
+		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+
+			var u = seq[ i ],
+				v = values[ u.id ];
+
+			if ( v.needsUpdate !== false ) {
+				// note: always updating when .needsUpdate is undefined
+
+				u.setValue( gl, v.value, renderer );
+
+			}
+
+		}
+
+	};
+
+	WebGLUniforms.seqWithValue = function( seq, values ) {
+
+		var r = [];
+
+		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+
+			var u = seq[ i ];
+			if ( u.id in values ) r.push( u );
+
+		}
+
+		return r;
+
+	};
+
+	WebGLUniforms.splitDynamic = function( seq, values ) {
+
+		var r = null,
+			n = seq.length,
+			w = 0;
+
+		for ( var i = 0; i !== n; ++ i ) {
+
+			var u = seq[ i ],
+				v = values[ u.id ];
+
+			if ( v && v.dynamic === true ) {
+
+				if ( r === null ) r = [];
+				r.push( u );
+
+			} else {
+
+				// in-place compact 'seq', removing the matches
+				if ( w < i ) seq[ w ] = u;
+				++ w;
+
+			}
+
+		}
+
+		if ( w < n ) seq.length = w;
+
+		return r;
+
+	};
+
+	WebGLUniforms.evalDynamic = function( seq, values, object, camera ) {
+
+		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+
+			var v = values[ seq[ i ].id ],
+				f = v.onUpdateCallback;
+
+			if ( f !== undefined ) f.call( v, object, camera );
+
+		}
+
+	};
+
+	return WebGLUniforms;
+
+} )();
+

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

@@ -333,7 +333,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) {
 						gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
 
 						state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
-						renderer.setTexture( sprite.texture, 1 );
+						renderer.setTexture2D( sprite.texture, 1 );
 
 						gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
 

+ 2 - 2
src/renderers/webgl/plugins/SpritePlugin.js

@@ -223,11 +223,11 @@ THREE.SpritePlugin = function ( renderer, sprites ) {
 
 			if ( material.map && material.map.image && material.map.image.width ) {
 
-				renderer.setTexture( material.map, 0 );
+				renderer.setTexture2D( material.map, 0 );
 
 			} else {
 
-				renderer.setTexture( texture, 0 );
+				renderer.setTexture2D( texture, 0 );
 
 			}
 

+ 1 - 0
utils/build/includes/common.json

@@ -249,6 +249,7 @@
 	"src/renderers/webgl/WebGLShader.js",
 	"src/renderers/webgl/WebGLShadowMap.js",
 	"src/renderers/webgl/WebGLState.js",
+	"src/renderers/webgl/WebGLUniforms.js",
 	"src/renderers/webgl/plugins/LensFlarePlugin.js",
 	"src/renderers/webgl/plugins/SpritePlugin.js",
 	"src/Three.Legacy.js"