Browse Source

Merge branch 'dev' into refactor_flexible_skinning

Conflicts:
	build/three.js
	build/three.min.js
Ian Kerr 11 years ago
parent
commit
da425be8a9
99 changed files with 3103 additions and 2410 deletions
  1. 2 3
      README.md
  2. 116 523
      build/three.js
  3. 184 172
      build/three.min.js
  4. 6 0
      docs/api/core/Geometry.html
  5. 0 8
      docs/api/core/Object3D.html
  6. 1 1
      docs/api/loaders/ImageLoader.html
  7. 1 1
      docs/api/loaders/MaterialLoader.html
  8. 1 1
      examples/canvas_camera_orthographic2.html
  9. 1 1
      examples/canvas_interactive_cubes.html
  10. 1 0
      examples/index.html
  11. 0 0
      examples/js/cameras/CombinedCamera.js
  12. 8 1
      examples/js/controls/OrbitControls.js
  13. 53 41
      examples/js/controls/TrackballControls.js
  14. 3 3
      examples/js/controls/TransformControls.js
  15. 79 0
      examples/js/exporters/STLBinaryExporter.js
  16. 10 10
      examples/js/loaders/AWDLoader.js
  17. 23 5
      examples/js/loaders/ColladaLoader.js
  18. 310 0
      examples/js/loaders/DDSLoader.js
  19. 8 6
      examples/js/loaders/MTLLoader.js
  20. 0 0
      examples/js/loaders/SVGLoader.js
  21. 22 8
      examples/js/loaders/SceneLoader.js
  22. 451 0
      examples/js/loaders/TGALoader.js
  23. 4 4
      examples/js/loaders/UTF8Loader.js
  24. 31 15
      examples/js/loaders/ctm/CTMLoader.js
  25. 191 200
      examples/js/math/Lut.js
  26. BIN
      examples/textures/crate_color8.tga
  27. BIN
      examples/textures/crate_grey8.tga
  28. 1 1
      examples/webgl_animation_skinning_blending.html
  29. 4 4
      examples/webgl_buffergeometry.html
  30. 8 8
      examples/webgl_buffergeometry_custom_attributes_particles.html
  31. 2 2
      examples/webgl_buffergeometry_lines.html
  32. 3 3
      examples/webgl_buffergeometry_lines_indexed.html
  33. 4 4
      examples/webgl_buffergeometry_particles.html
  34. 2 2
      examples/webgl_buffergeometry_rawshader.html
  35. 4 4
      examples/webgl_buffergeometry_uint.html
  36. 1 1
      examples/webgl_camera.html
  37. 0 4
      examples/webgl_camera_logarithmicdepthbuffer.html
  38. 7 8
      examples/webgl_custom_attributes_particles.html
  39. 4 4
      examples/webgl_custom_attributes_particles2.html
  40. 3 4
      examples/webgl_custom_attributes_particles3.html
  41. 2 2
      examples/webgl_geometry_colors_lookuptable.html
  42. 1 3
      examples/webgl_geometry_extrude_shapes.html
  43. 5 9
      examples/webgl_geometry_extrude_splines.html
  44. 12 19
      examples/webgl_geometry_large_mesh.html
  45. 25 33
      examples/webgl_geometry_minecraft_ao.html
  46. 3 8
      examples/webgl_geometry_shapes.html
  47. 16 16
      examples/webgl_gpgpu_birds.html
  48. 18 24
      examples/webgl_interactive_cubes_gpu.html
  49. 366 0
      examples/webgl_interactive_raycasting_pointcloud.html
  50. 1 1
      examples/webgl_interactive_voxelpainter.html
  51. 12 11
      examples/webgl_kinect.html
  52. 1 1
      examples/webgl_lensflares.html
  53. 3 0
      examples/webgl_loader_json_objconverter.html
  54. 3 0
      examples/webgl_loader_obj_mtl.html
  55. 4 0
      examples/webgl_loader_scene.html
  56. 21 14
      examples/webgl_materials_texture_compressed.html
  57. 148 0
      examples/webgl_materials_texture_tga.html
  58. 1 2
      examples/webgl_panorama_equirectangular.html
  59. 3 52
      src/Three.js
  60. 0 0
      src/cameras/CubeCamera.js
  61. 9 9
      src/core/BufferAttribute.js
  62. 1 1
      src/core/BufferGeometry.js
  63. 18 5
      src/core/Face3.js
  64. 0 1
      src/core/Face4.js
  65. 54 32
      src/core/Object3D.js
  66. 17 420
      src/core/Raycaster.js
  67. 1 1
      src/extras/GeometryUtils.js
  68. 1 456
      src/extras/ImageUtils.js
  69. 9 4
      src/extras/geometries/CubeGeometry.js
  70. 27 24
      src/extras/helpers/ArrowHelper.js
  71. 1 2
      src/extras/helpers/VertexNormalsHelper.js
  72. 11 11
      src/extras/helpers/WireframeHelper.js
  73. 2 0
      src/extras/renderers/plugins/LensFlarePlugin.js
  74. 70 44
      src/loaders/Loader.js
  75. 1 1
      src/loaders/ObjectLoader.js
  76. 10 3
      src/loaders/XHRLoader.js
  77. 2 2
      src/materials/PointCloudMaterial.js
  78. 2 2
      src/math/Euler.js
  79. 2 2
      src/math/Matrix3.js
  80. 15 15
      src/math/Matrix4.js
  81. 9 3
      src/math/Quaternion.js
  82. 2 2
      src/math/Vector2.js
  83. 11 11
      src/math/Vector3.js
  84. 2 2
      src/math/Vector4.js
  85. 16 0
      src/objects/LOD.js
  86. 69 0
      src/objects/Line.js
  87. 287 0
      src/objects/Mesh.js
  88. 133 2
      src/objects/PointCloud.js
  89. 28 3
      src/objects/Sprite.js
  90. 1 1
      src/renderers/CanvasRenderer.js
  91. 4 4
      src/renderers/WebGLRenderer.js
  92. 1 1
      src/renderers/renderables/RenderableFace.js
  93. 46 51
      src/renderers/shaders/ShaderChunk.js
  94. 42 44
      src/renderers/shaders/ShaderLib.js
  95. 1 1
      src/renderers/webgl/WebGLProgram.js
  96. 2 1
      utils/build/externs/common.js
  97. 1 0
      utils/build/includes/common.json
  98. 0 2
      utils/build/includes/extras.json
  99. 1 0
      utils/build/includes/webgl.json

+ 2 - 3
README.md

@@ -37,8 +37,8 @@ This code creates a scene, a camera, and a geometric cube, and it adds the cube
 
 		geometry = new THREE.BoxGeometry( 200, 200, 200 );
 		material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
+
 		mesh = new THREE.Mesh( geometry, material );
-		
 		scene.add( mesh );
 
 		renderer = new THREE.CanvasRenderer();
@@ -50,7 +50,6 @@ This code creates a scene, a camera, and a geometric cube, and it adds the cube
 
 	function animate() {
 
-		// note: three.js includes requestAnimationFrame shim
 		requestAnimationFrame( animate );
 
 		mesh.rotation.x += 0.01;
@@ -62,7 +61,7 @@ This code creates a scene, a camera, and a geometric cube, and it adds the cube
 
 </script>
 ```
-If everything went well you should see [this](http://jsfiddle.net/Gy4w7/).
+If everything went well you should see [this](http://jsfiddle.net/Q7DLQ/).
 
 ### Change log ###
 

File diff suppressed because it is too large
+ 116 - 523
build/three.js


File diff suppressed because it is too large
+ 184 - 172
build/three.min.js


+ 6 - 0
docs/api/core/Geometry.html

@@ -225,12 +225,18 @@
 		
 		<div>Neither bounding boxes or bounding spheres are computed by default. They need to be explicitly computed, otherwise they are *null*.</div>
 
+		<h3>.merge( [page:Geometry geometry], [page:Matrix4 matrix], [page:Integer materialIndexOffset] )</h3>
+		<div>Merge two geometries or geometry and geometry from object (using object's transform)</div>
+
 		<h3>.mergeVertices()</h3>
 		<div>
 		Checks for duplicate vertices using hashmap.<br />
 		Duplicated vertices are removed and faces' vertices are updated.
 		</div>
 		
+		<h3>.makeGroups()</h3>
+		<div>Geometry splitting</div>
+		
 		<h3>.clone()</h3>
 		<div>
 		Creates a new clone of the Geometry.

+ 0 - 8
docs/api/core/Object3D.html

@@ -218,14 +218,6 @@
 		Executes the callback on this object and all descendants. 
 		</div>
 
-		<h3>.getDescendants( [page:Array array] )</h3>
-		<div>
-		array - optional argument that returns the the array with descendants.<br />
-		</div>
-		<div>
-		Searches whole subgraph recursively to add all objects in the array.
-		</div>
-
 		<h3>.updateMatrix()</h3>
 		<div>
 		Updates local transform.

+ 1 - 1
docs/api/loaders/ImageLoader.html

@@ -14,7 +14,7 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:LoadingManager manager)</h3>
+		<h3>[name]([page:LoadingManager manager])</h3>
         <div>
         manager -- The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
         </div>

+ 1 - 1
docs/api/loaders/MaterialLoader.html

@@ -14,7 +14,7 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:LoadingManager manager)</h3>
+		<h3>[name]([page:LoadingManager manager])</h3>
         <div>
         manager -- The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
         </div>

+ 1 - 1
examples/canvas_camera_orthographic2.html

@@ -21,7 +21,7 @@
 	<body>
 
 		<script src="../build/three.min.js"></script>
-		<script src="../src/extras/cameras/CombinedCamera.js"></script>
+		<script src="js/cameras/CombinedCamera.js"></script>
 
 		<script src="js/libs/stats.min.js"></script>
 

+ 1 - 1
examples/canvas_interactive_cubes.html

@@ -131,7 +131,7 @@
 					intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
 
 					var particle = new THREE.Sprite( particleMaterial );
-					particle.position = intersects[ 0 ].point;
+					particle.position.copy( intersects[ 0 ].point );
 					particle.scale.x = particle.scale.y = 16;
 					scene.add( particle );
 

+ 1 - 0
examples/index.html

@@ -158,6 +158,7 @@
 				"webgl_interactive_cubes_gpu",
 				"webgl_interactive_draggablecubes",
 				"webgl_interactive_particles",
+				"webgl_interactive_raycasting_pointcloud",
 				"webgl_interactive_voxelpainter",
 				"webgl_kinect",
 				"webgl_lensflares",

+ 0 - 0
src/extras/cameras/CombinedCamera.js → examples/js/cameras/CombinedCamera.js


+ 8 - 1
examples/js/controls/OrbitControls.js

@@ -98,6 +98,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 	var pan = new THREE.Vector3();
 
 	var lastPosition = new THREE.Vector3();
+	var lastQuaternion = new THREE.Quaternion();
 
 	var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
 
@@ -284,11 +285,17 @@ THREE.OrbitControls = function ( object, domElement ) {
 		scale = 1;
 		pan.set( 0, 0, 0 );
 
-		if ( lastPosition.distanceToSquared( this.object.position ) > EPS ) {
+		// update condition is:
+		// min(camera displacement, camera rotation in radians)^2 > EPS
+		// using small-angle approximation cos(x/2) = 1 - x^2 / 8
+
+		if ( lastPosition.distanceToSquared( this.object.position ) > EPS
+		    || 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) {
 
 			this.dispatchEvent( changeEvent );
 
 			lastPosition.copy( this.object.position );
+			lastQuaternion.copy (this.object.quaternion );
 
 		}
 

+ 53 - 41
examples/js/controls/TrackballControls.js

@@ -6,7 +6,7 @@
 THREE.TrackballControls = function ( object, domElement ) {
 
 	var _this = this;
-	var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM: 4, TOUCH_PAN: 5 };
+	var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
 
 	this.object = object;
 	this.domElement = ( domElement !== undefined ) ? domElement : document;
@@ -107,22 +107,30 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 	};
 
-	this.getMouseOnScreen = function ( pageX, pageY, vector ) {
+	var getMouseOnScreen = ( function () {
 
-		return vector.set(
-			( pageX - _this.screen.left ) / _this.screen.width,
-			( pageY - _this.screen.top ) / _this.screen.height
-		);
+		var vector = new THREE.Vector2();
 
-	};
+		return function ( pageX, pageY ) {
+
+			vector.set(
+				( pageX - _this.screen.left ) / _this.screen.width,
+				( pageY - _this.screen.top ) / _this.screen.height
+			);
+
+			return vector;
 
-	this.getMouseProjectionOnBall = (function(){
+		};
 
-		var objectUp = new THREE.Vector3(),
-		    mouseOnBall = new THREE.Vector3();
+	}() );
 
+	var getMouseProjectionOnBall = ( function () {
 
-		return function ( pageX, pageY, projection ) {
+		var vector = new THREE.Vector3();
+		var objectUp = new THREE.Vector3();
+		var mouseOnBall = new THREE.Vector3();
+
+		return function ( pageX, pageY ) {
 
 			mouseOnBall.set(
 				( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
@@ -156,14 +164,15 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 			_eye.copy( _this.object.position ).sub( _this.target );
 
-			projection.copy( _this.object.up ).setLength( mouseOnBall.y )
-			projection.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
-			projection.add( _eye.setLength( mouseOnBall.z ) );
+			vector.copy( _this.object.up ).setLength( mouseOnBall.y )
+			vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
+			vector.add( _eye.setLength( mouseOnBall.z ) );
 
-			return projection;
-		}
+			return vector;
 
-	}());
+		};
+
+	}() );
 
 	this.rotateCamera = (function(){
 
@@ -206,7 +215,7 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 	this.zoomCamera = function () {
 
-		if ( _state === STATE.TOUCH_ZOOM ) {
+		if ( _state === STATE.TOUCH_ZOOM_PAN ) {
 
 			var factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
 			_touchZoomDistanceStart = _touchZoomDistanceEnd;
@@ -403,25 +412,25 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _state === STATE.ROTATE && !_this.noRotate ) {
 
-			_this.getMouseProjectionOnBall( event.pageX, event.pageY, _rotateStart );
-			_rotateEnd.copy(_rotateStart)
+			_rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
+			_rotateEnd.copy( _rotateStart );
 
 		} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
 
-			_this.getMouseOnScreen( event.pageX, event.pageY, _zoomStart );
+			_zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
 			_zoomEnd.copy(_zoomStart);
 
 		} else if ( _state === STATE.PAN && !_this.noPan ) {
 
-			_this.getMouseOnScreen( event.pageX, event.pageY, _panStart );
+			_panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
 			_panEnd.copy(_panStart)
 
 		}
 
 		document.addEventListener( 'mousemove', mousemove, false );
 		document.addEventListener( 'mouseup', mouseup, false );
-		_this.dispatchEvent( startEvent );
 
+		_this.dispatchEvent( startEvent );
 
 	}
 
@@ -434,15 +443,15 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _state === STATE.ROTATE && !_this.noRotate ) {
 
-			_this.getMouseProjectionOnBall( event.pageX, event.pageY, _rotateEnd );
+			_rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
 
 		} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
 
-			_this.getMouseOnScreen( event.pageX, event.pageY, _zoomEnd );
+			_zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
 
 		} else if ( _state === STATE.PAN && !_this.noPan ) {
 
-			_this.getMouseOnScreen( event.pageX, event.pageY, _panEnd );
+			_panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
 
 		}
 
@@ -496,19 +505,20 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 			case 1:
 				_state = STATE.TOUCH_ROTATE;
-				_rotateEnd.copy( _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateStart ));
+				_rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
+				_rotateEnd.copy( _rotateStart );
 				break;
 
 			case 2:
-				_state = STATE.TOUCH_ZOOM;
+				_state = STATE.TOUCH_ZOOM_PAN;
 				var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 				var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 				_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
-				break;
 
-			case 3:
-				_state = STATE.TOUCH_PAN;
-				_panEnd.copy( _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panStart ));
+				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
+				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
+				_panStart.copy( getMouseOnScreen( x, y ) );
+				_panEnd.copy( _panStart );
 				break;
 
 			default:
@@ -530,17 +540,17 @@ THREE.TrackballControls = function ( object, domElement ) {
 		switch ( event.touches.length ) {
 
 			case 1:
-				_this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateEnd );
+				_rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
 				break;
 
 			case 2:
 				var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 				var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
-				_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy )
-				break;
+				_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
 
-			case 3:
-				_this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panEnd );
+				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
+				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
+				_panEnd.copy( getMouseOnScreen( x, y ) );
 				break;
 
 			default:
@@ -557,15 +567,17 @@ THREE.TrackballControls = function ( object, domElement ) {
 		switch ( event.touches.length ) {
 
 			case 1:
-				_rotateStart.copy( _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateEnd ));
+				_rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
+				_rotateStart.copy( _rotateEnd );
 				break;
 
 			case 2:
 				_touchZoomDistanceStart = _touchZoomDistanceEnd = 0;
-				break;
 
-			case 3:
-				_panStart.copy( _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panEnd ));
+				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
+				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
+				_panEnd.copy( getMouseOnScreen( x, y ) );
+				_panStart.copy( _panEnd );
 				break;
 
 		}

+ 3 - 3
examples/js/controls/TransformControls.js

@@ -720,7 +720,7 @@
 
 			event.preventDefault();
 
-			var pointer = event.touches ? event.touches[ 0 ] : event;
+			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
 			var intersect = intersectObjects( pointer, scope.gizmo[_mode].pickers.children );
 
@@ -747,7 +747,7 @@
 			event.preventDefault();
 			event.stopPropagation();
 
-			var pointer = event.touches ? event.touches[ 0 ] : event;
+			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
 			if ( pointer.button === 0 || pointer.button === undefined ) {
 
@@ -791,7 +791,7 @@
 			event.preventDefault();
 			event.stopPropagation();
 
-			var pointer = event.touches? event.touches[0] : event;
+			var pointer = event.changedTouches? event.changedTouches[0] : event;
 
 			var planeIntersect = intersectObjects( pointer, [scope.gizmo[_mode].activePlane] );
 

+ 79 - 0
examples/js/exporters/STLBinaryExporter.js

@@ -0,0 +1,79 @@
+/**
+ * @author kovacsv / http://kovacsv.hu/
+ * @author mrdoob / http://mrdoob.com/
+ * @author mudcube / http://mudcu.be/
+ */
+ 
+THREE.STLBinaryExporter = function () {};
+
+THREE.STLBinaryExporter.prototype = {
+
+	constructor: THREE.STLBinaryExporter,
+
+	parse: ( function () {
+
+		var vector = new THREE.Vector3();
+		var normalMatrixWorld = new THREE.Matrix3();
+
+		return function ( scene ) {
+
+			var triangles = 0;
+			scene.traverse( function ( object ) {
+				if ( !(object instanceof THREE.Mesh) ) return;
+				triangles += object.geometry.faces.length;
+			});
+
+			var offset = 80; // skip header
+			var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
+			var arrayBuffer = new ArrayBuffer(bufferLength);
+			var output = new DataView(arrayBuffer);
+			output.setUint32(offset, triangles, true); offset += 4;
+
+			scene.traverse( function ( object ) {
+
+				if ( !(object instanceof THREE.Mesh) ) return;
+				if ( !(object.geometry instanceof THREE.Geometry )) return;
+
+				var geometry = object.geometry;
+				var matrixWorld = object.matrixWorld;
+
+				var vertices = geometry.vertices;
+				var faces = geometry.faces;
+
+				normalMatrixWorld.getNormalMatrix( matrixWorld );
+
+				for ( var i = 0, l = faces.length; i < l; i ++ ) {
+
+					var face = faces[ i ];
+
+					vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+
+					output.setFloat32(offset, vector.x, true); offset += 4; // normal
+					output.setFloat32(offset, vector.y, true); offset += 4;
+					output.setFloat32(offset, vector.z, true); offset += 4;
+
+					var indices = [ face.a, face.b, face.c ];
+
+					for ( var j = 0; j < 3; j ++ ) {
+
+						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( matrixWorld );
+
+						output.setFloat32(offset, vector.x, true); offset += 4; // vertices
+						output.setFloat32(offset, vector.y, true); offset += 4;
+						output.setFloat32(offset, vector.z, true); offset += 4;
+
+					}
+
+					output.setUint16(offset, 0, true); offset += 2; // attribute byte count					
+
+				}
+
+			} );
+			
+			return output;
+
+		};
+
+	}() )
+
+};

+ 10 - 10
examples/js/loaders/AWDLoader.js

@@ -735,8 +735,8 @@ THREE.AWDLoader = (function (){
         // ------------------
         if ( str_type === 1 ) {
 
-          attrib = new THREE.Float32Attribute( ( str_len / 12 ) * 3, 3 );
-          buffer = attrib.array;
+          buffer = new Float32Array( ( str_len / 12 ) * 3 );
+          attrib = new THREE.BufferAttribute( buffer, 3 );
 
           geom.addAttribute( 'position', attrib );
           idx = 0;
@@ -754,7 +754,8 @@ THREE.AWDLoader = (function (){
         // -----------------
         else if (str_type === 2) {
 
-          attrib = new THREE.Uint16Attribute( ( str_len / 2 ), 1 );
+          buffer = new Uint16Array( str_len / 2 );
+          attrib = new THREE.BufferAttribute( buffer, 1 );
           geom.addAttribute( 'index', attrib );
 
           geom.offsets.push({
@@ -763,7 +764,6 @@ THREE.AWDLoader = (function (){
             count: str_len/2
           });
 
-          buffer = attrib.array;
           idx = 0;
 
           while (this._ptr < str_end) {
@@ -778,8 +778,8 @@ THREE.AWDLoader = (function (){
         // -------------------
         else if (str_type === 3) {
 
-          attrib = new THREE.Float32Attribute( ( str_len / 8 ) * 2, 2 );
-          buffer = attrib.array;
+          buffer = new Float32Array( ( str_len / 8 ) * 2 );
+          attrib = new THREE.BufferAttribute( buffer, 2 );
 
           geom.addAttribute( 'uv', attrib );
           idx = 0;
@@ -794,10 +794,10 @@ THREE.AWDLoader = (function (){
         // NORMALS
         else if (str_type === 4) {
 
-          attrib = new THREE.Float32Attribute( ( str_len / 12 ) * 3, 3 );
+          buffer = new Float32Array( ( str_len / 12 ) * 3 );
+          attrib = new THREE.BufferAttribute( buffer, 3 );
           geom.addAttribute( 'normal', attrib );
-          buffer = attrib.array
-          idx = 0
+          idx = 0;
 
           while (this._ptr < str_end) {
             buffer[idx]   = -this.readF32();
@@ -1222,4 +1222,4 @@ THREE.AWDLoader = (function (){
 
   return AWDLoader;
 
-})();
+})();

+ 23 - 5
examples/js/loaders/ColladaLoader.js

@@ -3433,10 +3433,7 @@ THREE.ColladaLoader = function () {
 		if (this['transparency'] !== undefined && this['transparent'] !== undefined) {
 			// convert transparent color RBG to average value
 			var transparentColor = this['transparent'];
-			var transparencyLevel = (this.transparent.color.r +
-										this.transparent.color.g +
-										this.transparent.color.b)
-										/ 3 * this.transparency;
+			var transparencyLevel = (this.transparent.color.r + this.transparent.color.g + this.transparent.color.b) / 3 * this.transparency;
 
 			if (transparencyLevel > 0) {
 				transparent = true;
@@ -3483,7 +3480,28 @@ THREE.ColladaLoader = function () {
 
 								if (image) {
 
-									var texture = THREE.ImageUtils.loadTexture(baseUrl + image.init_from);
+									var url = baseUrl + image.init_from;
+
+									var texture;
+									var loader = THREE.Loader.Handlers.get( url );
+
+									if ( loader !== null ) {
+
+										texture = loader.load( url );
+
+									} else {
+
+										texture = new THREE.Texture( new Image() );
+										loader = new THREE.ImageLoader();
+										loader.load( url, function ( image ) {
+
+											texture.image = image;
+											texture.needsUpdate = true;
+
+										} );
+
+									}
+									
 									texture.wrapS = cot.texOpts.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
 									texture.wrapT = cot.texOpts.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
 									texture.offset.x = cot.texOpts.offsetU;

+ 310 - 0
examples/js/loaders/DDSLoader.js

@@ -0,0 +1,310 @@
+/*
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.DDSLoader = function () {};
+
+THREE.DDSLoader.prototype = {
+
+	constructor: THREE.DDSLoader,
+
+	load: function ( url, onLoad, onError ) {
+
+		var scope = this;
+
+		var images = [];
+
+		var texture = new THREE.CompressedTexture();
+		texture.image = images;
+
+		// no flipping for cube textures
+		// (also flipping doesn't work for compressed textures )
+
+		texture.flipY = false;
+
+		// can't generate mipmaps for compressed textures
+		// mips must be embedded in DDS files
+
+		texture.generateMipmaps = false;
+
+		if ( url instanceof Array ) {
+
+			// TODO
+
+			if ( onLoad ) onLoad( texture );
+
+		} else {
+
+			var loader = new THREE.XHRLoader();
+			loader.setResponseType( 'arraybuffer' );
+			loader.load( url, function ( buffer ) {
+
+				var dds = scope.parse( buffer, true );
+
+				if ( dds.isCubemap ) {
+
+					var faces = dds.mipmaps.length / dds.mipmapCount;
+
+					for ( var f = 0; f < faces; f ++ ) {
+
+						images[ f ] = { mipmaps : [] };
+
+						for ( var i = 0; i < dds.mipmapCount; i ++ ) {
+
+							images[ f ].mipmaps.push( dds.mipmaps[ f * dds.mipmapCount + i ] );
+							images[ f ].format = dds.format;
+							images[ f ].width = dds.width;
+							images[ f ].height = dds.height;
+
+						}
+
+					}
+
+				} else {
+
+					texture.image.width = dds.width;
+					texture.image.height = dds.height;
+					texture.mipmaps = dds.mipmaps;
+
+				}
+
+				texture.format = dds.format;
+				texture.needsUpdate = true;
+
+				if ( onLoad ) onLoad( texture );
+
+			} );
+
+		}
+
+		return texture;
+
+	},
+
+	parse: function ( buffer, loadMipmaps ) {
+
+		var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
+
+		// Adapted from @toji's DDS utils
+		//	https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
+
+		// All values and structures referenced from:
+		// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
+
+		var DDS_MAGIC = 0x20534444;
+
+		var DDSD_CAPS = 0x1,
+			DDSD_HEIGHT = 0x2,
+			DDSD_WIDTH = 0x4,
+			DDSD_PITCH = 0x8,
+			DDSD_PIXELFORMAT = 0x1000,
+			DDSD_MIPMAPCOUNT = 0x20000,
+			DDSD_LINEARSIZE = 0x80000,
+			DDSD_DEPTH = 0x800000;
+
+		var DDSCAPS_COMPLEX = 0x8,
+			DDSCAPS_MIPMAP = 0x400000,
+			DDSCAPS_TEXTURE = 0x1000;
+
+		var DDSCAPS2_CUBEMAP = 0x200,
+			DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
+			DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
+			DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
+			DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
+			DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
+			DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
+			DDSCAPS2_VOLUME = 0x200000;
+
+		var DDPF_ALPHAPIXELS = 0x1,
+			DDPF_ALPHA = 0x2,
+			DDPF_FOURCC = 0x4,
+			DDPF_RGB = 0x40,
+			DDPF_YUV = 0x200,
+			DDPF_LUMINANCE = 0x20000;
+
+		function fourCCToInt32( value ) {
+
+			return value.charCodeAt(0) +
+				(value.charCodeAt(1) << 8) +
+				(value.charCodeAt(2) << 16) +
+				(value.charCodeAt(3) << 24);
+
+		}
+
+		function int32ToFourCC( value ) {
+
+			return String.fromCharCode(
+				value & 0xff,
+				(value >> 8) & 0xff,
+				(value >> 16) & 0xff,
+				(value >> 24) & 0xff
+			);
+		}
+
+		function loadARGBMip( buffer, dataOffset, width, height ) {
+			var dataLength = width*height*4;
+			var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength );
+			var byteArray = new Uint8Array( dataLength );
+			var dst = 0;
+			var src = 0;
+			for ( var y = 0; y < height; y++ ) {
+				for ( var x = 0; x < width; x++ ) {
+					var b = srcBuffer[src]; src++;
+					var g = srcBuffer[src]; src++;
+					var r = srcBuffer[src]; src++;
+					var a = srcBuffer[src]; src++;
+					byteArray[dst] = r; dst++;	//r
+					byteArray[dst] = g; dst++;	//g
+					byteArray[dst] = b; dst++;	//b
+					byteArray[dst] = a; dst++;	//a
+				}
+			}
+			return byteArray;
+		}
+
+		var FOURCC_DXT1 = fourCCToInt32("DXT1");
+		var FOURCC_DXT3 = fourCCToInt32("DXT3");
+		var FOURCC_DXT5 = fourCCToInt32("DXT5");
+
+		var headerLengthInt = 31; // The header length in 32 bit ints
+
+		// Offsets into the header array
+
+		var off_magic = 0;
+
+		var off_size = 1;
+		var off_flags = 2;
+		var off_height = 3;
+		var off_width = 4;
+
+		var off_mipmapCount = 7;
+
+		var off_pfFlags = 20;
+		var off_pfFourCC = 21;
+		var off_RGBBitCount = 22;
+		var off_RBitMask = 23;
+		var off_GBitMask = 24;
+		var off_BBitMask = 25;
+		var off_ABitMask = 26;
+
+		var off_caps = 27;
+		var off_caps2 = 28;
+		var off_caps3 = 29;
+		var off_caps4 = 30;
+
+		// Parse header
+
+		var header = new Int32Array( buffer, 0, headerLengthInt );
+
+		if ( header[ off_magic ] !== DDS_MAGIC ) {
+
+			console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' );
+			return dds;
+
+		}
+
+		if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) {
+
+			console.error( 'THREE.DDSLoader.parse: Unsupported format, must contain a FourCC code.' );
+			return dds;
+
+		}
+
+		var blockBytes;
+
+		var fourCC = header[ off_pfFourCC ];
+
+		var isRGBAUncompressed = false;
+
+		switch ( fourCC ) {
+
+			case FOURCC_DXT1:
+
+				blockBytes = 8;
+				dds.format = THREE.RGB_S3TC_DXT1_Format;
+				break;
+
+			case FOURCC_DXT3:
+
+				blockBytes = 16;
+				dds.format = THREE.RGBA_S3TC_DXT3_Format;
+				break;
+
+			case FOURCC_DXT5:
+
+				blockBytes = 16;
+				dds.format = THREE.RGBA_S3TC_DXT5_Format;
+				break;
+
+			default:
+
+				if( header[off_RGBBitCount] ==32 
+					&& header[off_RBitMask]&0xff0000
+					&& header[off_GBitMask]&0xff00 
+					&& header[off_BBitMask]&0xff
+					&& header[off_ABitMask]&0xff000000  ) {
+					isRGBAUncompressed = true;
+					blockBytes = 64;
+					dds.format = THREE.RGBAFormat;
+				} else {
+					console.error( 'THREE.DDSLoader.parse: Unsupported FourCC code ', int32ToFourCC( fourCC ) );
+					return dds;
+				}
+		}
+
+		dds.mipmapCount = 1;
+
+		if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
+
+			dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
+
+		}
+
+		//TODO: Verify that all faces of the cubemap are present with DDSCAPS2_CUBEMAP_POSITIVEX, etc.
+
+		dds.isCubemap = header[ off_caps2 ] & DDSCAPS2_CUBEMAP ? true : false;
+
+		dds.width = header[ off_width ];
+		dds.height = header[ off_height ];
+
+		var dataOffset = header[ off_size ] + 4;
+
+		// Extract mipmaps buffers
+
+		var width = dds.width;
+		var height = dds.height;
+
+		var faces = dds.isCubemap ? 6 : 1;
+
+		for ( var face = 0; face < faces; face ++ ) {
+
+			for ( var i = 0; i < dds.mipmapCount; i ++ ) {
+
+				if( isRGBAUncompressed ) {
+					var byteArray = loadARGBMip( buffer, dataOffset, width, height );
+					var dataLength = byteArray.length;
+				} else {
+					var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;
+					var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
+				}
+				
+				var mipmap = { "data": byteArray, "width": width, "height": height };
+				dds.mipmaps.push( mipmap );
+
+				dataOffset += dataLength;
+
+				width = Math.max( width * 0.5, 1 );
+				height = Math.max( height * 0.5, 1 );
+
+			}
+
+			width = dds.width;
+			height = dds.height;
+
+		}
+
+		return dds;
+
+	}
+
+};

+ 8 - 6
examples/js/loaders/MTLLoader.js

@@ -363,18 +363,18 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 	loadTexture: function ( url, mapping, onLoad, onError ) {
 
-		var isCompressed = /\.dds$/i.test( url );
+		var texture;
+		var loader = THREE.Loader.Handlers.get( url );
 
-		if ( isCompressed ) {
+		if ( loader !== null ) {
 
-			var texture = THREE.ImageUtils.loadCompressedTexture( url, mapping, onLoad, onError );
+			texture = loader.load( url, onLoad );
 
 		} else {
 
-			var image = new Image();
-			var texture = new THREE.Texture( image, mapping );
+			texture = new THREE.Texture( new Image() );
 
-			var loader = new THREE.ImageLoader();
+			loader = new THREE.ImageLoader();
 			loader.crossOrigin = this.crossOrigin;
 			loader.load( url, function ( image ) {
 
@@ -387,6 +387,8 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 		}
 
+		texture.mapping = mapping;
+
 		return texture;
 
 	}

+ 0 - 0
src/loaders/SVGLoader.js → examples/js/loaders/SVGLoader.js


+ 22 - 8
examples/js/loaders/SceneLoader.js

@@ -944,22 +944,24 @@ THREE.SceneLoader.prototype = {
 
 			}
 
+			var texture;
+
 			if ( textureJSON.url instanceof Array ) {
 
 				var count = textureJSON.url.length;
 				var url_array = [];
 
-				for( var i = 0; i < count; i ++ ) {
+				for ( var i = 0; i < count; i ++ ) {
 
 					url_array[ i ] = get_url( textureJSON.url[ i ], data.urlBaseType );
 
 				}
 
-				var isCompressed = /\.dds$/i.test( url_array[ 0 ] );
+				var loader = THREE.Loader.Handlers.get( url_array[ 0 ] );
 
-				if ( isCompressed ) {
+				if ( loader !== null ) {
 
-					texture = THREE.ImageUtils.loadCompressedTextureCube( url_array, textureJSON.mapping, generateTextureCallback( count ) );
+					texture = loader.load( url_array, generateTextureCallback( count ) );
 
 				} else {
 
@@ -969,20 +971,32 @@ THREE.SceneLoader.prototype = {
 
 			} else {
 
-				var isCompressed = /\.dds$/i.test( textureJSON.url );
 				var fullUrl = get_url( textureJSON.url, data.urlBaseType );
 				var textureCallback = generateTextureCallback( 1 );
 
-				if ( isCompressed ) {
+				var loader = THREE.Loader.Handlers.get( fullUrl );
+
+				if ( loader !== null ) {
 
-					texture = THREE.ImageUtils.loadCompressedTexture( fullUrl, textureJSON.mapping, textureCallback );
+					texture = loader.load( fullUrl, textureCallback );
 
 				} else {
 
-					texture = THREE.ImageUtils.loadTexture( fullUrl, textureJSON.mapping, textureCallback );
+					texture = new THREE.Texture( new Image() );
+					loader = new THREE.ImageLoader();
+					loader.load( fullUrl, function ( image ) {
+
+						texture.image = image;
+						texture.needsUpdate = true;
+
+						textureCallback();
+
+					} );
 
 				}
 
+				texture.mapping = textureJSON.mapping;
+
 				if ( THREE[ textureJSON.minFilter ] !== undefined )
 					texture.minFilter = THREE[ textureJSON.minFilter ];
 

+ 451 - 0
examples/js/loaders/TGALoader.js

@@ -0,0 +1,451 @@
+/*
+ * @author Daosheng Mu / https://github.com/DaoshengMu/
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.TGALoader = function () {};
+
+THREE.TGALoader.prototype = {
+
+	constructor: THREE.TGALoader,
+
+	load: function ( url, onLoad, onError ) {
+		
+		var scope = this;
+		
+		var texture = new THREE.DataTexture();
+
+		var loader = new THREE.XHRLoader();
+		loader.setResponseType( 'arraybuffer' );
+		loader.load( url, function ( buffer ) {
+
+			texture.image = scope.parse( buffer );
+			texture.needsUpdate = true;
+
+			if ( onLoad ) onLoad( texture );
+
+		} );
+
+		return texture;
+
+	},
+
+	// reference from vthibault, https://github.com/vthibault/roBrowser/blob/master/src/Loaders/Targa.js
+	parse: function ( buffer ) {
+			   
+		// TGA Constants
+		var TGA_TYPE_NO_DATA = 0,
+		TGA_TYPE_INDEXED = 1,
+		TGA_TYPE_RGB = 2,
+		TGA_TYPE_GREY = 3,
+		TGA_TYPE_RLE_INDEXED = 9,
+		TGA_TYPE_RLE_RGB = 10,
+		TGA_TYPE_RLE_GREY = 11,
+
+		TGA_ORIGIN_MASK = 0x30,
+		TGA_ORIGIN_SHIFT = 0x04,
+		TGA_ORIGIN_BL = 0x00,
+		TGA_ORIGIN_BR = 0x01,
+		TGA_ORIGIN_UL = 0x02,
+		TGA_ORIGIN_UR = 0x03;
+
+		
+		if ( buffer.length < 19 )
+			console.error( 'THREE.TGALoader.parse: Not enough data to contain header.' );
+		
+		var content = new Uint8Array( buffer ),
+			offset = 0,
+			header = {
+				id_length:       content[ offset ++ ], 
+				colormap_type:   content[ offset ++ ],
+				image_type:      content[ offset ++ ],
+				colormap_index:  content[ offset ++ ] | content[ offset ++ ] << 8,
+				colormap_length: content[ offset ++ ] | content[ offset ++ ] << 8,
+				colormap_size:   content[ offset ++ ],
+
+				origin: [
+					content[ offset ++ ] | content[ offset ++ ] << 8,
+					content[ offset ++ ] | content[ offset ++ ] << 8
+				],
+				width:      content[ offset ++ ] | content[ offset ++ ] << 8,
+				height:     content[ offset ++ ] | content[ offset ++ ] << 8,
+				pixel_size: content[ offset ++ ],
+				flags:      content[ offset ++ ]
+			};
+				
+		function tgaCheckHeader( header ) {
+
+			switch( header.image_type ) {
+
+				// Check indexed type
+				case TGA_TYPE_INDEXED:
+				case TGA_TYPE_RLE_INDEXED:
+					if ( header.colormap_length > 256 || header.colormap_size !== 24 || header.colormap_type !== 1) {
+						console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for indexed type');
+					}
+					break;
+
+				// Check colormap type
+				case TGA_TYPE_RGB:
+				case TGA_TYPE_GREY:
+				case TGA_TYPE_RLE_RGB:
+				case TGA_TYPE_RLE_GREY:
+					if (header.colormap_type) {
+						console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for colormap type');
+					}
+					break;
+
+				// What the need of a file without data ?
+				case TGA_TYPE_NO_DATA:
+					console.error('THREE.TGALoader.parse.tgaCheckHeader: No data');
+
+				// Invalid type ?
+				default:
+					console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid type " '+ header.image_type + '"');
+
+			}
+
+			// Check image width and height
+			if ( header.width <= 0 || header.height <=0 ) {
+				console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid image size' );
+			}
+
+			// Check image pixel size 
+			if (header.pixel_size !== 8  &&
+				header.pixel_size !== 16 &&
+				header.pixel_size !== 24 &&
+				header.pixel_size !== 32) {
+				console.error('THREE.TGALoader.parse.tgaCheckHeader: Invalid pixel size "' + header.pixel_size + '"');
+			}
+
+		}
+
+		// Check tga if it is valid format
+		tgaCheckHeader( header );
+
+		if ( header.id_length + offset > buffer.length ) {
+			console.error('THREE.TGALoader.parse: No data');
+		}
+
+		// Skip the needn't data
+		offset += header.id_length;
+
+		// Get targa information about RLE compression and palette
+		var use_rle = false, 
+			use_pal = false, 
+			use_grey = false;
+	
+		switch ( header.image_type ) {
+
+			case TGA_TYPE_RLE_INDEXED:
+				use_rle = true;
+				use_pal = true;
+				break;
+
+			case TGA_TYPE_INDEXED:
+				use_pal = true;
+				break;
+				
+			case TGA_TYPE_RLE_RGB:
+				use_rle = true;
+				break;
+
+			case TGA_TYPE_RGB:
+				break;
+
+			case TGA_TYPE_RLE_GREY:
+				use_rle = true;
+				use_grey = true;
+				break;
+
+			case TGA_TYPE_GREY:
+				use_grey = true;
+				break;
+
+		}
+		
+		// Parse tga image buffer
+		function tgaParse( use_rle, use_pal, header, offset, data ) {
+			
+			var pixel_data,
+				pixel_size,
+				pixel_total,
+				palettes;
+		
+				pixel_size = header.pixel_size >> 3;
+				pixel_total = header.width * header.height * pixel_size;
+				
+			 // Read palettes
+			 if ( use_pal ) {
+				 palettes = data.subarray( offset, offset += header.colormap_length * ( header.colormap_size >> 3 ) );
+			 }
+			 
+			 // Read RLE
+			 if ( use_rle ) {
+				 pixel_data = new Uint8Array(pixel_total);
+				 
+				var c, count, i;
+				var shift = 0;
+				var pixels = new Uint8Array(pixel_size);
+
+				while (shift < pixel_total) {
+					c     = data[offset++];
+					count = (c & 0x7f) + 1;
+
+					// RLE pixels.
+					if (c & 0x80) {
+						// Bind pixel tmp array
+						for (i = 0; i < pixel_size; ++i) {
+								pixels[i] = data[offset++];
+						}
+
+						// Copy pixel array
+						for (i = 0; i < count; ++i) {
+								pixel_data.set(pixels, shift + i * pixel_size);
+						}
+
+						shift += pixel_size * count;
+
+					} else {
+						// Raw pixels.
+						count *= pixel_size;
+						for (i = 0; i < count; ++i) {
+								pixel_data[shift + i] = data[offset++];
+						}
+						shift += count;
+					}
+				}
+			 } else {
+				// RAW Pixels
+				pixel_data = data.subarray(
+					 offset, offset += (use_pal ? header.width * header.height : pixel_total)
+				);
+			 }
+			
+			 return { 
+				pixel_data: pixel_data, 
+				palettes: palettes 
+			 };
+		}
+		
+		function tgaGetImageData8bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image, palettes) {
+
+			var colormap = palettes;
+			var color, i = 0, x, y;
+					var width = header.width;
+					
+			for (y = y_start; y !== y_end; y += y_step) {
+				for (x = x_start; x !== x_end; x += x_step, i++) {
+					color = image[i];
+					imageData[(x + width * y) * 4 + 3] = 255;
+					imageData[(x + width * y) * 4 + 2] = colormap[(color * 3) + 0];
+					imageData[(x + width * y) * 4 + 1] = colormap[(color * 3) + 1];
+					imageData[(x + width * y) * 4 + 0] = colormap[(color * 3) + 2];
+				}
+			}
+
+			return imageData;
+
+		};
+
+		function tgaGetImageData16bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
+
+			var color, i = 0, x, y;
+			var width = header.width;
+
+			for (y = y_start; y !== y_end; y += y_step) {
+				for (x = x_start; x !== x_end; x += x_step, i += 2) {
+					color = image[i + 0] + (image[i + 1] << 8); // Inversed ?
+					imageData[(x + width * y) * 4 + 0] = (color & 0x7C00) >> 7;
+					imageData[(x + width * y) * 4 + 1] = (color & 0x03E0) >> 2;
+					imageData[(x + width * y) * 4 + 2] = (color & 0x001F) >> 3;
+					imageData[(x + width * y) * 4 + 3] = (color & 0x8000) ? 0 : 255;
+				}
+			}
+
+			return imageData;
+
+		};
+
+		function tgaGetImageData24bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {
+
+			var i = 0, x, y;
+			var width = header.width;
+
+			for (y = y_start; y !== y_end; y += y_step) {
+				for (x = x_start; x !== x_end; x += x_step, i += 3) {
+					imageData[(x + width * y) * 4 + 3] = 255;
+					imageData[(x + width * y) * 4 + 2] = image[i + 0];
+					imageData[(x + width * y) * 4 + 1] = image[i + 1];
+					imageData[(x + width * y) * 4 + 0] = image[i + 2];
+				}
+			}
+
+			return imageData;
+
+		};
+		
+		function tgaGetImageData32bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {		
+
+			var i = 0, x, y;
+			var width = header.width;
+
+			for (y = y_start; y !== y_end; y += y_step) {
+				for (x = x_start; x !== x_end; x += x_step, i += 4) {
+					imageData[(x + width * y) * 4 + 2] = image[i + 0];
+					imageData[(x + width * y) * 4 + 1] = image[i + 1];
+					imageData[(x + width * y) * 4 + 0] = image[i + 2];
+					imageData[(x + width * y) * 4 + 3] = image[i + 3];
+				}
+			}
+
+			return imageData;
+
+		};
+
+		function tgaGetImageDataGrey8bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
+
+			var color, i = 0, x, y;
+			var width = header.width;
+
+			for (y = y_start; y !== y_end; y += y_step) {
+				for (x = x_start; x !== x_end; x += x_step, i++) {
+					color = image[i];
+					imageData[(x + width * y) * 4 + 0] = color;
+					imageData[(x + width * y) * 4 + 1] = color;
+					imageData[(x + width * y) * 4 + 2] = color;
+					imageData[(x + width * y) * 4 + 3] = 255;
+				}
+			}
+
+			return imageData;
+
+		};
+
+		function tgaGetImageDataGrey16bits(imageData, y_start, y_step, y_end, x_start, x_step, x_end, image) {		
+
+			var i = 0, x, y;
+			var width = header.width;
+
+			for (y = y_start; y !== y_end; y += y_step) {
+				for (x = x_start; x !== x_end; x += x_step, i += 2) {
+					imageData[(x + width * y) * 4 + 0] = image[i + 0];
+					imageData[(x + width * y) * 4 + 1] = image[i + 0];
+					imageData[(x + width * y) * 4 + 2] = image[i + 0];
+					imageData[(x + width * y) * 4 + 3] = image[i + 1];
+				}
+			}
+
+			return imageData;
+
+		};
+	
+		function getTgaRGBA( width, height, image, palette ) {
+
+			var x_start,
+				y_start,
+				x_step,
+				y_step,
+				x_end,
+				y_end,                    
+				data = new Uint8Array(width * height * 4);
+				
+			switch( (header.flags & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT ) {
+				default:
+				case TGA_ORIGIN_UL:
+					x_start = 0;
+					x_step = 1;
+					x_end = width;
+					y_start = 0;
+					y_step = 1;
+					y_end = height;
+					break;
+					
+				case TGA_ORIGIN_BL:
+					x_start = 0;
+					x_step = 1;
+					x_end = width;
+					y_start = height - 1;
+					y_step = -1;
+					y_end = -1;
+					break;
+					
+				case TGA_ORIGIN_UR:
+					x_start = width - 1;
+					x_step = -1;
+					x_end = -1;
+					y_start = 0;
+					y_step = 1;
+					y_end = height;
+					break;
+					
+				case TGA_ORIGIN_BR:
+					x_start = width - 1;
+					x_step = -1;
+					x_end = -1;
+					y_start = height - 1;
+					y_step = -1;
+					y_end = -1;
+					break;
+
+			}	
+				
+			if ( use_grey ) {
+				
+				switch( header.pixel_size ) {
+					case 8:
+						tgaGetImageDataGrey8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+						break;
+					case 16:
+						tgaGetImageDataGrey16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+						break;
+					default:
+						console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
+						break;
+				}
+				
+			} else {
+				
+				switch( header.pixel_size ) {
+					case 8:
+						tgaGetImageData8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette );
+						break;
+						
+					case 16:
+						tgaGetImageData16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+						break;
+						
+					case 24:
+						tgaGetImageData24bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+						break;
+
+					case 32:
+						tgaGetImageData32bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
+						break;
+						
+					default:
+						console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
+						break;  
+				}
+
+			}
+
+			// Load image data according to specific method
+			// var func = 'tgaGetImageData' + (use_grey ? 'Grey' : '') + (header.pixel_size) + 'bits';
+			// func(data, y_start, y_step, y_end, x_start, x_step, x_end, width, image, palette );
+			return data;
+
+		}
+		
+		var result = tgaParse( use_rle, use_pal, header, offset, content );
+		var rgbaData = getTgaRGBA( header.width, header.height, result.pixel_data, result.palettes );
+		
+		return {
+			width: header.width,
+			height: header.height,
+			data: rgbaData
+		};
+
+	}
+
+};

+ 4 - 4
examples/js/loaders/UTF8Loader.js

@@ -94,10 +94,10 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 	}
 
-    geometry.addAttribute( 'index', new THREE.Uint32Attribute( indices, 1 ) );
-    geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
-    geometry.addAttribute( 'normal', new THREE.Float32Attribute( normals, 3 ) );
-    geometry.addAttribute( 'uv', new THREE.Float32Attribute( uvs, 2 ) );
+    geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+    geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+    geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+    geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
 
     geometry.offsets.push( { start: 0, count: indices.length, index: 0 } );
 

+ 31 - 15
examples/js/loaders/ctm/CTMLoader.js

@@ -190,38 +190,54 @@ THREE.CTMLoader.prototype.load = function( url, callback, parameters ) {
 
 THREE.CTMLoader.prototype.createModel = function ( file, callback ) {
 
-	var Model = function ( ) {
+	var Model = function () {
 
 		THREE.BufferGeometry.call( this );
 
 		this.materials = [];
 
-		// init GL buffers
 		var indices = file.body.indices,
 		positions = file.body.vertices,
 		normals = file.body.normals;
 
 		var uvs, colors;
 
-		if ( file.body.uvMaps !== undefined && file.body.uvMaps.length > 0 ) {
-			uvs = file.body.uvMaps[ 0 ].uv;
+		var uvMaps = file.body.uvMaps;
+
+		if ( uvMaps !== undefined && uvMaps.length > 0 ) {
+
+			uvs = uvMaps[ 0 ].uv;
+
+		}
+
+		var attrMaps = file.body.attrMaps;
+
+		if ( attrMaps !== undefined && attrMaps.length > 0 && attrMaps[ 0 ].name === 'Color' ) {
+
+			colors = attrMaps[ 0 ].attr;
+
 		}
 
-		if ( file.body.attrMaps !== undefined && file.body.attrMaps.length > 0 && file.body.attrMaps[ 0 ].name === "Color" ) {
-			colors = file.body.attrMaps[ 0 ].attr;
+		this.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+		this.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+
+		if ( normals !== undefined ) {
+
+			this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+
 		}
 
-		this.addAttribute( 'index', new THREE.Uint32Attribute( indices, 1 ) );
-		this.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
+		if ( uvs !== undefined ) {
+
+			this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
 
-		if ( normals !== undefined ) 
-			this.addAttribute( 'normal', new THREE.Float32Attribute( normals, 3 ) );
+		}
+
+		if ( colors !== undefined ) {
 
-		if ( uvs !== undefined ) 
-			this.addAttribute( 'uv', new THREE.Float32Attribute( uvs, 2 ) );
+			this.addAttribute( 'color', new THREE.BufferAttribute( colors, 4 ) );
 
-		if ( colors !== undefined ) 
-			this.addAttribute( 'color', new THREE.Float32Attribute( colors, 4 ) );
+		}
 
 	}
 
@@ -238,4 +254,4 @@ THREE.CTMLoader.prototype.createModel = function ( file, callback ) {
 
 	callback( geometry );
 
-};
+};

+ 191 - 200
examples/js/math/Lut.js

@@ -11,9 +11,9 @@ THREE.Lut = function ( colormap, numberofcolors ) {
 
 	var step = 1.0 / this.n;
 
-	for ( var i = 0; i <= 1; i+=step ) {
+	for ( var i = 0; i <= 1; i += step ) {
 
-		for ( var j = 0; j < this.map.length - 1; j++ ) {
+		for ( var j = 0; j < this.map.length - 1; j ++ ) {
 
 			if ( i >= this.map[ j ][ 0 ] && i < this.map[ j + 1 ][ 0 ] ) {
 
@@ -28,9 +28,9 @@ THREE.Lut = function ( colormap, numberofcolors ) {
 
 				this.lut.push(color);
 
-			}         
+			}
 
-		}   
+		}
 
 	}
 
@@ -88,7 +88,7 @@ THREE.Lut.prototype = {
 
 	},
 
-  copy: function ( lut ) {
+	copy: function ( lut ) {
 
 		this.lut = lut.lut;
 		this.mapname = lut.mapname;
@@ -101,371 +101,362 @@ THREE.Lut.prototype = {
 
 	},
 
-  getColor: function ( alpha ) {
+	getColor: function ( alpha ) {
 
-	if ( alpha <= this.minV ) {
+		if ( alpha <= this.minV ) {
 
-		alpha = this.minV;
+			alpha = this.minV;
 
-	}   
+		} else if ( alpha >= this.maxV ) {
 
-	 else if ( alpha >= this.maxV ) {
+			alpha = this.maxV;
 
-		alpha = this.maxV;
+		}
 
-	}
+		alpha = ( alpha - this.minV ) / ( this.maxV - this.minV );
 
-	alpha = ( alpha - this.minV ) / ( this.maxV - this.minV );
+		var colorPosition = Math.round ( alpha * this.n );
+		colorPosition == this.n ? colorPosition -= 1 : colorPosition;
 
-	var colorPosition = Math.round ( alpha * this.n );
-	colorPosition == this.n ? colorPosition -= 1 : colorPosition;
+		return this.lut[ colorPosition ];
 
-	return this.lut[ colorPosition ];
+	},
 
-  },
+	addColorMap: function ( colormapName, arrayOfColors ) {
 
-  addColorMap: function ( colormapName, arrayOfColors ) {
+		THREE.ColorMapKeywords[ colormapName ] = arrayOfColors;
 
-	THREE.ColorMapKeywords[ colormapName ] = arrayOfColors;
+	},
 
-  },
+	setLegendOn: function ( parameters ) {
 
-  setLegendOn: function ( parameters ) {
+		if ( parameters === undefined ) { parameters = {}; }
 
-	if ( parameters === undefined ) { parameters = {}; }
+		this.legend = {};
 
-	this.legend = {};
+		this.legend.layout = parameters.hasOwnProperty( 'layout' ) ? parameters[ 'layout' ] : 'vertical';
 
-	this.legend.layout = parameters.hasOwnProperty( 'layout' ) ? parameters[ 'layout' ] : 'vertical';
+		this.legend.position = parameters.hasOwnProperty( 'position' ) ? parameters[ 'position' ] : { 'x': 21.5, 'y': 8, 'z': 5 };
 
-	this.legend.position = parameters.hasOwnProperty( 'position' ) ? parameters[ 'position' ] : { 'x': 21.5, 'y': 8, 'z': 5 };
+		this.legend.dimensions = parameters.hasOwnProperty( 'dimensions' ) ? parameters[ 'dimensions' ] : { 'width': 0.5, 'height': 3 };
 
-	this.legend.dimensions = parameters.hasOwnProperty( 'dimensions' ) ? parameters[ 'dimensions' ] : { 'width': 0.5, 'height': 3 };
+		this.legend.canvas = document.createElement( 'canvas' );
 
-	this.legend.canvas = document.createElement( 'canvas' );
+		this.legend.canvas.setAttribute( 'id', 'legend' );
+		this.legend.canvas.setAttribute( 'hidden', true );
 
-	this.legend.canvas.setAttribute( 'id', 'legend' );
-	this.legend.canvas.setAttribute( 'hidden', true );
+		document.body.appendChild( this.legend.canvas );
 
-	document.body.appendChild( this.legend.canvas );
+		this.legend.ctx = this.legend.canvas.getContext( '2d' );
 
-	this.legend.ctx = this.legend.canvas.getContext( '2d' );
+		this.legend.canvas.setAttribute( 'width',  1 );
+		this.legend.canvas.setAttribute( 'height', this.n );
 
-	this.legend.canvas.setAttribute( 'width',  1 );
-	this.legend.canvas.setAttribute( 'height', this.n );
+		this.legend.texture = new THREE.Texture( this.legend.canvas );
 
-	this.legend.texture = new THREE.Texture( this.legend.canvas );
+		imageData = this.legend.ctx.getImageData( 0, 0, 1, this.n );
 
-	imageData = this.legend.ctx.getImageData( 0, 0, 1, this.n );
+		data = imageData.data;
+		len = data.length;
 
-	data = imageData.data;
-	len = data.length;
+		this.map = THREE.ColorMapKeywords[ this.mapname ];
 
-	this.map = THREE.ColorMapKeywords[ this.mapname ];
+		var k = 0;
 
-	var k = 0;
+		var step = 1.0 / this.n;
 
-	var step = 1.0 / this.n;
+		for ( var i = 1; i >= 0; i-=step ) {
 
-	for ( var i = 1; i >= 0; i-=step ) {
+			for ( var j = this.map.length - 1; j >= 0; j-- ) {
 
-		for ( var j = this.map.length - 1; j >= 0; j-- ) {
+				if ( i < this.map[ j ][ 0 ] && i >= this.map[ j - 1 ][ 0 ]  ) {
 
-			if ( i < this.map[ j ][ 0 ] && i >= this.map[ j - 1 ][ 0 ]  ) {
+					var min = this.map[ j - 1 ][ 0 ];
+					var max = this.map[ j ][ 0 ];
+					var color = new THREE.Color( 0xffffff );
+					var minColor = new THREE.Color( 0xffffff ).setHex( this.map[ j - 1][ 1 ] );
+					var maxColor = new THREE.Color( 0xffffff ).setHex( this.map[ j ][ 1 ] );
+					color = minColor.lerp( maxColor, ( i - min ) / ( max - min ) );
 
-				var min = this.map[ j - 1 ][ 0 ];
-				var max = this.map[ j ][ 0 ];
-				var color = new THREE.Color( 0xffffff );
-				var minColor = new THREE.Color( 0xffffff ).setHex( this.map[ j - 1][ 1 ] );
-				var maxColor = new THREE.Color( 0xffffff ).setHex( this.map[ j ][ 1 ] );
-				color = minColor.lerp( maxColor, ( i - min ) / ( max - min ) );
+					data[ k * 4     ] = Math.round( color.r * 255 );
+					data[ k * 4 + 1 ] = Math.round( color.g * 255 );
+					data[ k * 4 + 2 ] = Math.round( color.b * 255 );
+					data[ k * 4 + 3 ] = 255;
 
-				data[ k * 4     ] = Math.round( color.r * 255 );
-				data[ k * 4 + 1 ] = Math.round( color.g * 255 );
-				data[ k * 4 + 2 ] = Math.round( color.b * 255 );
-				data[ k * 4 + 3 ] = 255;
+					k+=1;
 
-				k+=1;
+				}
 
 			}
 
 		}
 
-	}   
-
-	this.legend.ctx.putImageData( imageData, 0, 0 );
-	this.legend.texture.needsUpdate = true;
-
-	this.legend.legendGeometry = new THREE.PlaneGeometry( this.legend.dimensions.width , this.legend.dimensions.height  );
-	this.legend.legendMaterial = new THREE.MeshBasicMaterial( { map : this.legend.texture, side : THREE.DoubleSide } );
+		this.legend.ctx.putImageData( imageData, 0, 0 );
+		this.legend.texture.needsUpdate = true;
 
-	this.legend.mesh = new THREE.Mesh( this.legend.legendGeometry, this.legend.legendMaterial );
+		this.legend.legendGeometry = new THREE.PlaneGeometry( this.legend.dimensions.width , this.legend.dimensions.height );
+		this.legend.legendMaterial = new THREE.MeshBasicMaterial( { map : this.legend.texture, side : THREE.DoubleSide } );
 
-	if ( this.legend.layout == 'horizontal') {
+		this.legend.mesh = new THREE.Mesh( this.legend.legendGeometry, this.legend.legendMaterial );
 
-		this.legend.mesh.rotation.z = - 90 * ( Math.PI / 180 );
+		if ( this.legend.layout == 'horizontal') {
 
-		this.legend.mesh.position = new THREE.Vector3( this.legend.position.x, this.legend.position.y, this.legend.position.z );
+			this.legend.mesh.rotation.z = - 90 * ( Math.PI / 180 );
 
-	}   
-
-	else {
+		}
 
-		this.legend.mesh.position = new THREE.Vector3( this.legend.position.x, this.legend.position.y, this.legend.position.z );
+		this.legend.mesh.position.copy( this.legend.position );
 
-	}
+		return this.legend.mesh;
 
-	return this.legend.mesh;
+	},
 
-  },
+	setLegendOff: function () {
 
-  setLegendOff: function () {
+		this.legend = null;
 
-	this.legend = null;
+		return this.legend;
 
-	return this.legend;
+	},
 
-  },
+	setLegendLayout: function ( layout ) {
 
-  setLegendLayout: function ( layout ) {
+		if ( ! this.legend ) { return false; }
 
-	if ( ! this.legend ) { return false; }
+		if ( this.legend.layout == layout ) { return false; }
 
-	if ( this.legend.layout == layout ) { return false; }
+		if ( layout != 'horizontal' && layout != 'vertical' ) { return false; }
 
-	if ( layout != 'horizontal' && layout != 'vertical' ) { return false; }
+		this.layout = layout;
 
-	this.layout = layout;
+		if ( layout == 'horizontal' ) {
 
-	if ( layout == 'horizontal' ) {
+			this.legend.mesh.rotation.z = 90 * ( Math.PI / 180 );
 
-		this.legend.mesh.rotation.z = 90 * ( Math.PI / 180 );
+		}
 
-	}
+		if ( layout == 'vertical' ) {
 
-	if ( layout == 'vertical' ) {
+			this.legend.mesh.rotation.z = -90 * ( Math.PI / 180 );
 
-		this.legend.mesh.rotation.z = -90 * ( Math.PI / 180 );
+		}
 
-	}
+		return this.legend.mesh;
 
-	return this.legend.mesh;
+	},
 
-  },
+	setLegendPosition: function ( position ) {
 
-  setLegendPosition: function ( position ) {
+		this.legend.position = new THREE.Vector3( position.x, position.y, position.z );
 
-	this.legend.position = new THREE.Vector3( position.x, position.y, position.z );
+		return this.legend;
 
-	return this.legend;
+	},
 
-  },
+	setLegendLabels: function ( parameters, callback ) {
 
+		if ( ! this.legend ) { return false; }
 
-  setLegendLabels: function ( parameters, callback ) {
+		if ( typeof parameters === 'function') { callback = parameters; }
 
-	if ( ! this.legend ) { return false; }
+		if ( parameters === undefined ) { parameters = {}; }
 
-	if ( typeof parameters === 'function') { callback = parameters; }
+		this.legend.labels = {};
 
-	if ( parameters === undefined ) { parameters = {}; }
+		this.legend.labels.fontsize = parameters.hasOwnProperty( 'fontsize' ) ? parameters[ 'fontsize' ] : 24;
 
-	this.legend.labels = {};
+		this.legend.labels.fontface = parameters.hasOwnProperty( 'fontface' ) ? parameters[ 'fontface' ] : 'Arial';
 
-	this.legend.labels.fontsize = parameters.hasOwnProperty( 'fontsize' ) ? parameters[ 'fontsize' ] : 24;
+		this.legend.labels.title = parameters.hasOwnProperty( 'title' ) ? parameters[ 'title' ] : '';
 
-	this.legend.labels.fontface = parameters.hasOwnProperty( 'fontface' ) ? parameters[ 'fontface' ] : 'Arial';
+		this.legend.labels.um = parameters.hasOwnProperty( 'um' ) ? ' [ '+ parameters[ 'um' ] + ' ]': '';
 
-	this.legend.labels.title = parameters.hasOwnProperty( 'title' ) ? parameters[ 'title' ] : '';
+		this.legend.labels.ticks = parameters.hasOwnProperty( 'ticks' ) ? parameters[ 'ticks' ] : 0;
 
-	this.legend.labels.um = parameters.hasOwnProperty( 'um' ) ? ' [ '+ parameters[ 'um' ] + ' ]': '';
+		this.legend.labels.decimal = parameters.hasOwnProperty( 'decimal' ) ? parameters[ 'decimal' ] : 2;
 
-	this.legend.labels.ticks = parameters.hasOwnProperty( 'ticks' ) ? parameters[ 'ticks' ] : 0;
+		this.legend.labels.notation = parameters.hasOwnProperty( 'notation' ) ? parameters[ 'notation' ] : 'standard';
 
-	this.legend.labels.decimal = parameters.hasOwnProperty( 'decimal' ) ? parameters[ 'decimal' ] : 2;
+		var backgroundColor = { r: 255, g: 100, b: 100, a: 0.8 };
+		var borderColor =  { r: 255, g: 0, b: 0, a: 1.0 };
+		var borderThickness = 4;
 
-	this.legend.labels.notation = parameters.hasOwnProperty( 'notation' ) ? parameters[ 'notation' ] : 'standard';
+		var canvasTitle = document.createElement( 'canvas' );
+		var contextTitle = canvasTitle.getContext( '2d' );
 
-	var backgroundColor = { r: 255, g: 100, b: 100, a: 0.8 };
-	var borderColor =  { r: 255, g: 0, b: 0, a: 1.0 };
-	var borderThickness = 4;
+		contextTitle.font = 'Normal ' + this.legend.labels.fontsize * 1.2 + 'px ' + this.legend.labels.fontface;
 
-	var canvasTitle = document.createElement( 'canvas' );
-	var contextTitle = canvasTitle.getContext( '2d' );
+		var metrics = contextTitle.measureText( this.legend.labels.title.toString() + this.legend.labels.um.toString() );
+		var textWidth = metrics.width;
 
-	contextTitle.font = 'Normal ' + this.legend.labels.fontsize * 1.2 + 'px ' + this.legend.labels.fontface;
+		contextTitle.fillStyle   = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + backgroundColor.a + ')';
 
-	var metrics = contextTitle.measureText( this.legend.labels.title.toString() + this.legend.labels.um.toString() );
-	var textWidth = metrics.width;
+		contextTitle.strokeStyle = 'rgba(' + borderColor.r + ',' + borderColor.g + ',' + borderColor.b + ',' + borderColor.a + ')';
 
-	contextTitle.fillStyle   = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + backgroundColor.a + ')';
+		contextTitle.lineWidth = borderThickness;
 
-	contextTitle.strokeStyle = 'rgba(' + borderColor.r + ',' + borderColor.g + ',' + borderColor.b + ',' + borderColor.a + ')';
+		contextTitle.fillStyle = 'rgba( 0, 0, 0, 1.0 )';
 
-	contextTitle.lineWidth = borderThickness;
+		contextTitle.fillText( this.legend.labels.title.toString() + this.legend.labels.um.toString(), borderThickness, this.legend.labels.fontsize + borderThickness );
 
-	contextTitle.fillStyle = 'rgba( 0, 0, 0, 1.0 )';
+		var txtTitle = new THREE.Texture( canvasTitle );
 
-	contextTitle.fillText( this.legend.labels.title.toString() + this.legend.labels.um.toString(), borderThickness, this.legend.labels.fontsize + borderThickness );
+		txtTitle.needsUpdate = true;
 
-	var txtTitle = new THREE.Texture( canvasTitle );
+		var spriteMaterialTitle = new THREE.SpriteMaterial( { map: txtTitle, useScreenCoordinates: false } );
 
-	txtTitle.needsUpdate = true;
+		var spriteTitle = new THREE.Sprite( spriteMaterialTitle );
 
-	var spriteMaterialTitle = new THREE.SpriteMaterial( { map: txtTitle, useScreenCoordinates: false } );
+		spriteTitle.scale.set( 2, 1, 1.0 );
 
-	var spriteTitle = new THREE.Sprite( spriteMaterialTitle );
+		if ( this.legend.layout == 'vertical' ) {
 
-	spriteTitle.scale.set( 2, 1, 1.0 );
+			spriteTitle.position.set( this.legend.position.x + this.legend.dimensions.width, this.legend.position.y + ( this.legend.dimensions.height * 0.45 ), this.legend.position.z );
 
-	if ( this.legend.layout == 'vertical' ) {
+		}
 
-		spriteTitle.position.set( this.legend.position.x + this.legend.dimensions.width, this.legend.position.y + ( this.legend.dimensions.height * 0.45 ), this.legend.position.z );
+		if ( this.legend.layout == 'horizontal' ) {
 
-	}
+			spriteTitle.position.set( this.legend.position.x * 1.015, this.legend.position.y + ( this.legend.dimensions.height * 0.03 ), this.legend.position.z );
 
-	if ( this.legend.layout == 'horizontal' ) {
+		}
 
-		spriteTitle.position.set( this.legend.position.x * 1.015, this.legend.position.y + ( this.legend.dimensions.height * 0.03 ), this.legend.position.z );
+		if ( this.legend.labels.ticks > 0 ) {
 
-	}
+			var ticks = {};
+			var lines = {};
 
-	if ( this.legend.labels.ticks > 0 ) {
-
-		var ticks = {};
-		var lines = {};
+			if ( this.legend.layout == 'vertical' ) {
 
-		if ( this.legend.layout == 'vertical' ) {
+				var topPositionY = this.legend.position.y + ( this.legend.dimensions.height * 0.36 );
+				var bottomPositionY = this.legend.position.y - ( this.legend.dimensions.height * 0.61 );
 
-			var topPositionY = this.legend.position.y + ( this.legend.dimensions.height * 0.36 );
-			var bottomPositionY = this.legend.position.y - ( this.legend.dimensions.height * 0.61 );
+			}
 
-		}
+			if ( this.legend.layout == 'horizontal' ) {
 
-		if ( this.legend.layout == 'horizontal' ) {
+				var topPositionX = this.legend.position.x + ( this.legend.dimensions.height * 0.75 );
+				var bottomPositionX = this.legend.position.x - ( this.legend.dimensions.width * 1.2  ) ;
 
-			var topPositionX = this.legend.position.x + ( this.legend.dimensions.height * 0.75 );
-			var bottomPositionX = this.legend.position.x - ( this.legend.dimensions.width * 1.2  ) ;
+			}
 
-		}
+			for ( var i = 0; i < this.legend.labels.ticks; i++ ) {
 
-		for ( var i = 0; i < this.legend.labels.ticks; i++ ) {
+				var value = ( this.maxV - this.minV ) / ( this.legend.labels.ticks - 1  ) * i ;
 
-			var value = ( this.maxV - this.minV ) / ( this.legend.labels.ticks - 1  ) * i ;
+				if ( callback ) {
 
-			if ( callback ) {
+					value = callback ( value );
 
-				value = callback ( value );
+				}
 
-			}
+				else {
 
-			else {
+					if ( this.legend.labels.notation == 'scientific' ) {
 
-				if ( this.legend.labels.notation == 'scientific' ) {
+						value = value.toExponential( this.legend.labels.decimal );
 
-					value = value.toExponential( this.legend.labels.decimal );
+					}
 
-				}
+					else {
 
-				else {
+						value = value.toFixed( this.legend.labels.decimal );
 
-					value = value.toFixed( this.legend.labels.decimal );
+					}
 
 				}
 
-			}       
+				var canvasTick = document.createElement( 'canvas' );
+				var contextTick = canvasTick.getContext( '2d' );
 
-			var canvasTick = document.createElement( 'canvas' );
-			var contextTick = canvasTick.getContext( '2d' );
+				contextTick.font = 'Normal ' + this.legend.labels.fontsize + 'px ' + this.legend.labels.fontface;
 
-			contextTick.font = 'Normal ' + this.legend.labels.fontsize + 'px ' + this.legend.labels.fontface;
+				var metrics = contextTick.measureText( value.toString() );
+				var textWidth = metrics.width;
 
-			var metrics = contextTick.measureText( value.toString() );
-			var textWidth = metrics.width;
+				contextTick.fillStyle   = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + backgroundColor.a + ')';
 
-			contextTick.fillStyle   = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + backgroundColor.a + ')';
+				contextTick.strokeStyle = 'rgba(' + borderColor.r + ',' + borderColor.g + ',' + borderColor.b + ',' + borderColor.a + ')';
 
-			contextTick.strokeStyle = 'rgba(' + borderColor.r + ',' + borderColor.g + ',' + borderColor.b + ',' + borderColor.a + ')';
+				contextTick.lineWidth = borderThickness;
 
-			contextTick.lineWidth = borderThickness;
+				contextTick.fillStyle = 'rgba( 0, 0, 0, 1.0 )';
 
-			contextTick.fillStyle = 'rgba( 0, 0, 0, 1.0 )';
+				contextTick.fillText( value.toString(), borderThickness, this.legend.labels.fontsize + borderThickness );
 
-			contextTick.fillText( value.toString(), borderThickness, this.legend.labels.fontsize + borderThickness );
+				var txtTick = new THREE.Texture( canvasTick );
 
-			var txtTick = new THREE.Texture( canvasTick );
+				txtTick.needsUpdate = true;
 
-			txtTick.needsUpdate = true;
+				var spriteMaterialTick = new THREE.SpriteMaterial( { map: txtTick, useScreenCoordinates: false } );
 
-			var spriteMaterialTick = new THREE.SpriteMaterial( { map: txtTick, useScreenCoordinates: false } );
+				var spriteTick = new THREE.Sprite( spriteMaterialTick );
 
-			var spriteTick = new THREE.Sprite( spriteMaterialTick );
+				spriteTick.scale.set( 2, 1, 1.0 );
 
-			spriteTick.scale.set( 2, 1, 1.0 );
+				if ( this.legend.layout == 'vertical' ) {
 
-			if ( this.legend.layout == 'vertical' ) {
+					var position = bottomPositionY + ( topPositionY - bottomPositionY ) * ( value / ( this.maxV - this.minV ) );
 
-				var position = bottomPositionY + ( topPositionY - bottomPositionY ) * ( value / ( this.maxV - this.minV ) );
+					spriteTick.position.set( this.legend.position.x + ( this.legend.dimensions.width * 2.7 ), position, this.legend.position.z );
 
-				spriteTick.position.set( this.legend.position.x + ( this.legend.dimensions.width * 2.7 ), position, this.legend.position.z );
+				}
 
-			}
+				if ( this.legend.layout == 'horizontal' ) {
 
-			if ( this.legend.layout == 'horizontal' ) {
+					var position = bottomPositionX + ( topPositionX - bottomPositionX ) * ( value / ( this.maxV - this.minV ) );
 
-				var position = bottomPositionX + ( topPositionX - bottomPositionX ) * ( value / ( this.maxV - this.minV ) );
+					if ( this.legend.labels.ticks > 5 ) {
 
-				if ( this.legend.labels.ticks > 5 ) {
+						if ( i % 2 === 0 ) { var offset = 1.7; }
 
-					if ( i % 2 === 0 ) { var offset = 1.7; }
+						else { var offset = 2.1; }
 
-					else { var offset = 2.1; }
+					}
 
-				}             
+					else { var offset = 1.7; }
 
-				else { var offset = 1.7; }
+					spriteTick.position.set( position, this.legend.position.y - this.legend.dimensions.width * offset, this.legend.position.z );
 
-				spriteTick.position.set( position, this.legend.position.y - this.legend.dimensions.width * offset, this.legend.position.z );
+				}
 
-			}       
+				var material = new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 2 } );
 
-			var material = new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 2 } );
+				var geometry = new THREE.Geometry();
 
-			var geometry = new THREE.Geometry();
 
+				if ( this.legend.layout == 'vertical' ) {
 
-			if ( this.legend.layout == 'vertical' ) {
+					var linePosition = ( this.legend.position.y - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( value / ( this.maxV - this.minV ) * 0.99 );
 
-				var linePosition = ( this.legend.position.y - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( value / ( this.maxV - this.minV ) * 0.99 );
+					geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.55, linePosition , this.legend.position.z  ) );
 
-				geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.55, linePosition , this.legend.position.z  ) );
+					geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.7, linePosition, this.legend.position.z  ) );
 
-				geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.7, linePosition, this.legend.position.z  ) );
+				}
 
-			}
+				if ( this.legend.layout == 'horizontal' ) {
 
-			if ( this.legend.layout == 'horizontal' ) {
+					var linePosition = ( this.legend.position.x - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( value / ( this.maxV - this.minV ) * 0.99 );
 
-				var linePosition = ( this.legend.position.x - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( value / ( this.maxV - this.minV ) * 0.99 );
+					geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.55, this.legend.position.z  ) );
 
-				geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.55, this.legend.position.z  ) );
+					geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.7, this.legend.position.z  ) );
 
-				geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.7, this.legend.position.z  ) );
+				}
 
-			}       
+				var line = new THREE.Line( geometry, material );
 
-			var line = new THREE.Line( geometry, material );
+				lines[ i ] = line;
+				ticks[ i ] = spriteTick;
 
-			lines[ i ] = line;
-			ticks[ i ] = spriteTick;
+			}
 
 		}
 
-	}
-
-	return { 'title': spriteTitle,  'ticks': ticks, 'lines': lines };
+		return { 'title': spriteTitle,  'ticks': ticks, 'lines': lines };
 
-  }
+	}
 
 };
 

BIN
examples/textures/crate_color8.tga


BIN
examples/textures/crate_grey8.tga


+ 1 - 1
examples/webgl_animation_skinning_blending.html

@@ -64,7 +64,7 @@
 				scene.add ( new THREE.AmbientLight( 0xaaaaaa ) );
 
 				var light = new THREE.DirectionalLight( 0xffffff, 1.5 );
-				light.position = new THREE.Vector3( 0, 0, 1000.0 );
+				light.position.set( 0, 0, 1000 );
 				scene.add( light );
 
 				renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false } );

+ 4 - 4
examples/webgl_buffergeometry.html

@@ -195,10 +195,10 @@
 
 				}
 
-				geometry.addAttribute( 'index', new THREE.Uint16Attribute( indices, 1 ) );
-				geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
-				geometry.addAttribute( 'normal', new THREE.Float32Attribute( normals, 3 ) );
-				geometry.addAttribute( 'color', new THREE.Float32Attribute( colors, 3 ) );
+				geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 
 				var offsets = triangles / chunkSize;
 

+ 8 - 8
examples/webgl_buffergeometry_custom_attributes_particles.html

@@ -114,14 +114,14 @@
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 
-				uniforms: 		uniforms,
+				uniforms:       uniforms,
 				attributes:     attributes,
 				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
 				fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
 
-				blending: 		THREE.AdditiveBlending,
-				depthTest: 		false,
-				transparent:	true
+				blending:       THREE.AdditiveBlending,
+				depthTest:      false,
+				transparent:    true
 
 			});
 
@@ -152,11 +152,11 @@
 
 			}
 
-			geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
-			geometry.addAttribute( 'customColor', new THREE.Float32Attribute( values_color, 3 ) );
-			geometry.addAttribute( 'size', new THREE.Float32Attribute( values_size, 1 ) );
+			geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+			geometry.addAttribute( 'customColor', new THREE.BufferAttribute( values_color, 3 ) );
+			geometry.addAttribute( 'size', new THREE.BufferAttribute( values_size, 1 ) );
 
-			particleSystem = new THREE.ParticleSystem( geometry, shaderMaterial );
+			particleSystem = new THREE.PointCloud( geometry, shaderMaterial );
 
 			scene.add( particleSystem );
 

+ 2 - 2
examples/webgl_buffergeometry_lines.html

@@ -94,8 +94,8 @@
 
 				}
 
-				geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
-				geometry.addAttribute( 'color', new THREE.Float32Attribute( colors, 3 ) );
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 
 				geometry.computeBoundingSphere();
 

+ 3 - 3
examples/webgl_buffergeometry_lines_indexed.html

@@ -182,9 +182,9 @@
 				);
 				// --------------------------------
 
-				geometry.addAttribute( 'index', new THREE.Uint16Attribute( indices_array, 1 ) );
-				geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
-				geometry.addAttribute( 'color', new THREE.Float32Attribute( colors, 3 ) );
+				geometry.addAttribute( 'index', new THREE.BufferAttribute( new Uint16Array( indices_array ), 1 ) );
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
 				geometry.computeBoundingSphere();
 
 				mesh = new THREE.Line( geometry, material, THREE.LinePieces );

+ 4 - 4
examples/webgl_buffergeometry_particles.html

@@ -102,16 +102,16 @@
 
 				}
 
-				geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
-				geometry.addAttribute( 'color', new THREE.Float32Attribute( colors, 3 ) );
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 
 				geometry.computeBoundingSphere();
 
 				//
 
-				var material = new THREE.ParticleSystemMaterial( { size: 15, vertexColors: true } );
+				var material = new THREE.PointCloudMaterial( { size: 15, vertexColors: true } );
 
-				particleSystem = new THREE.ParticleSystem( geometry, material );
+				particleSystem = new THREE.PointCloud( geometry, material );
 				scene.add( particleSystem );
 
 				//

+ 2 - 2
examples/webgl_buffergeometry_rawshader.html

@@ -113,7 +113,7 @@
 
 				var geometry = new THREE.BufferGeometry();
 
-				var vertices = new THREE.Float32Attribute( triangles * 3 * 3, 3 );
+				var vertices = new THREE.BufferAttribute( new Float32Array( triangles * 3 * 3 ), 3 );
 
 				for ( var i = 0; i < vertices.length; i ++ ) {
 
@@ -123,7 +123,7 @@
 
 				geometry.addAttribute( 'position', vertices );
 
-				var colors = new THREE.Float32Attribute( triangles * 3 * 4, 4 );
+				var colors = new THREE.BufferAttribute(new Float32Array( triangles * 3 * 4 ), 4 );
 
 				for ( var i = 0; i < colors.length; i ++ ) {
 

+ 4 - 4
examples/webgl_buffergeometry_uint.html

@@ -190,10 +190,10 @@
 
 				}
 
-				geometry.addAttribute( 'index', new THREE.Uint32Attribute( indices, 1 ) );
-				geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) );
-				geometry.addAttribute( 'normal', new THREE.Float32Attribute( normals, 3 ) );
-				geometry.addAttribute( 'color', new THREE.Float32Attribute( colors, 3 ) );
+				geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 
 				geometry.computeBoundingSphere();
 

+ 1 - 1
examples/webgl_camera.html

@@ -130,7 +130,7 @@
 
 				}
 
-				var particles = new THREE.ParticleSystem( geometry, new THREE.ParticleSystemMaterial( { color: 0x888888 } ) );
+				var particles = new THREE.PointCloud( geometry, new THREE.PointCloudMaterial( { color: 0x888888 } ) );
 				scene.add( particles );
 
 				//

+ 0 - 4
examples/webgl_camera_logarithmicdepthbuffer.html

@@ -168,10 +168,6 @@
 				light.position.set(100,100,100);
 				scene.add(light);
 
-				var pointlight = new THREE.PointLight(0xffccaa, .1);
-				pointlight.position = camera.position;
-				scene.add(pointlight);
-
 				var materialargs = {
 					color: 0xffffff,
 					specular: 0xffaa00,

+ 7 - 8
examples/webgl_custom_attributes_particles.html

@@ -119,14 +119,14 @@
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 
-				uniforms: 		uniforms,
+				uniforms:       uniforms,
 				attributes:     attributes,
 				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
 				fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
 
-				blending: 		THREE.AdditiveBlending,
-				depthTest: 		false,
-				transparent:	true
+				blending:       THREE.AdditiveBlending,
+				depthTest:      false,
+				transparent:    true
 
 			});
 
@@ -134,7 +134,7 @@
 			var radius = 200;
 			var geometry = new THREE.Geometry();
 
-			for ( var i = 0; i < 100000; i++ ) {
+			for ( var i = 0; i < 100000; i ++ ) {
 
 				var vertex = new THREE.Vector3();
 				vertex.x = Math.random() * 2 - 1;
@@ -146,7 +146,7 @@
 
 			}
 
-			sphere = new THREE.ParticleSystem( geometry, shaderMaterial );
+			sphere = new THREE.PointCloud( geometry, shaderMaterial );
 
 			sphere.dynamic = true;
 			//sphere.sortParticles = true;
@@ -155,8 +155,7 @@
 			var values_size = attributes.size.value;
 			var values_color = attributes.customColor.value;
 
-
-			for( var v = 0; v < vertices.length; v++ ) {
+			for ( var v = 0; v < vertices.length; v++ ) {
 
 				values_size[ v ] = 10;
 				values_color[ v ] = new THREE.Color( 0xffaa00 );

+ 4 - 4
examples/webgl_custom_attributes_particles2.html

@@ -117,11 +117,11 @@
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 
-				uniforms: 		uniforms,
+				uniforms:       uniforms,
 				attributes:     attributes,
 				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
 				fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
-				transparent:	true
+				transparent:    true
 
 			});
 
@@ -134,7 +134,7 @@
 			var geometry2 = new THREE.BoxGeometry( 0.8 * radius, 0.8 * radius, 0.8 * radius, 10, 10, 10 );
 			geometry.merge( geometry2 );
 
-			sphere = new THREE.ParticleSystem( geometry, shaderMaterial );
+			sphere = new THREE.PointCloud( geometry, shaderMaterial );
 
 			sphere.dynamic = true;
 			sphere.sortParticles = true;
@@ -143,7 +143,7 @@
 			var values_size = attributes.size.value;
 			var values_color = attributes.ca.value;
 
-			for( var v = 0; v < vertices.length; v++ ) {
+			for ( var v = 0; v < vertices.length; v ++ ) {
 
 				values_size[ v ] = 10;
 				values_color[ v ] = new THREE.Color( 0xffffff );

+ 3 - 4
examples/webgl_custom_attributes_particles3.html

@@ -125,7 +125,7 @@
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 
-				uniforms: 		uniforms,
+				uniforms:       uniforms,
 				attributes:     attributes,
 				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
 				fragmentShader: document.getElementById( 'fragmentshader' ).textContent
@@ -193,8 +193,7 @@
 
 			// particle system
 
-			object = new THREE.ParticleSystem( geometry, shaderMaterial );
-			object.dynamic = true;
+			object = new THREE.PointCloud( geometry, shaderMaterial );
 
 			// custom attributes
 
@@ -203,7 +202,7 @@
 			var values_size = attributes.size.value;
 			var values_color = attributes.ca.value;
 
-			for( var v = 0; v < vertices.length; v ++ ) {
+			for ( var v = 0; v < vertices.length; v ++ ) {
 
 				values_size[ v ] = 10;
 				values_color[ v ] = new THREE.Color( 0xffffff );

+ 2 - 2
examples/webgl_geometry_colors_lookuptable.html

@@ -205,7 +205,7 @@
 
 					}
 
-					geometry.addAttribute( 'color', new THREE.Float32Attribute( new Float32Array( lutColors ), 3) );
+					geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( lutColors ), 3 ) );
 
 					mesh = new THREE.Mesh ( geometry, material );
 
@@ -346,4 +346,4 @@
 		</script>
 
 	</body>
-</html>
+</html>

+ 1 - 3
examples/webgl_geometry_extrude_shapes.html

@@ -61,13 +61,11 @@
 				scene.add( new THREE.AmbientLight( 0x222222 ) );
 
 				var light = new THREE.PointLight( 0xffffff );
-				light.position = camera.position;
+				light.position.copy( camera.position );
 				scene.add( light );
 
-
 				//
 
-
 				var closedSpline = new THREE.ClosedSplineCurve3( [
 					new THREE.Vector3( -60, -100,  60 ),
 					new THREE.Vector3( -60,   20,  60 ),

+ 5 - 9
examples/webgl_geometry_extrude_splines.html

@@ -95,7 +95,6 @@
 		dropdown += '</select>';
 
 		var closed2 = true;
-		var debug = true;
 		var parent;
 		var tube, tubeMesh;
 		var animation = false, lookAhead = false;
@@ -108,16 +107,15 @@
 
 			var segments = parseInt(document.getElementById('segments').value);
 			closed2 = document.getElementById('closed').checked;
-			debug = document.getElementById('debug').checked;
 
 			var radiusSegments = parseInt(document.getElementById('radiusSegments').value);
 
-			console.log('adding tube', value, closed2, debug, radiusSegments);
+			console.log('adding tube', value, closed2, radiusSegments);
 			if (tubeMesh) parent.remove(tubeMesh);
 
 			extrudePath = splines[value];
 
-			tube = new THREE.TubeGeometry(extrudePath, segments, 2, radiusSegments, closed2, debug);
+			tube = new THREE.TubeGeometry(extrudePath, segments, 2, radiusSegments, closed2);
 
 			addGeometry(tube, 0xff00ff);
 			setScale();
@@ -148,8 +146,6 @@
 					transparent: true
 			})]);
 
-			if ( geometry.debug ) tubeMesh.add( geometry.debug );
-
 			parent.add( tubeMesh );
 
 		}
@@ -192,7 +188,7 @@
 			info.innerHTML += '<br/>Scale: <select id="scale" onchange="setScale()"><option>1</option><option>2</option><option selected>4</option><option>6</option><option>10</option></select>';
 			info.innerHTML += '<br/>Extrusion Segments: <select onchange="addTube()" id="segments"><option>50</option><option selected>100</option><option>200</option><option>400</option></select>';
 			info.innerHTML += '<br/>Radius Segments: <select id="radiusSegments" onchange="addTube()"><option>1</option><option>2</option><option selected>3</option><option>4</option><option>5</option><option>6</option><option>8</option><option>12</option></select>';
-			info.innerHTML += '<br/>Debug normals: <input id="debug" type="checkbox" onchange="addTube()"  /> Closed:<input id="closed" onchange="addTube()" type="checkbox" checked />';
+			info.innerHTML += '<br/>Closed:<input id="closed" onchange="addTube()" type="checkbox" checked />';
 
 			info.innerHTML += '<br/><br/><input id="animation" type="button" onclick="animateCamera(true)" value="Camera Spline Animation View: OFF"/><br/> Look Ahead <input id="lookAhead" type="checkbox" onchange="animateCamera()" /> Camera Helper <input id="cameraHelper" type="checkbox" onchange="animateCamera()" />';
 
@@ -369,8 +365,8 @@
 			// We move on a offset on its binormal
 			pos.add( normal.clone().multiplyScalar( offset ) );
 
-			splineCamera.position = pos;
-			cameraEye.position = pos;
+			splineCamera.position.copy( pos );
+			cameraEye.position.copy( pos );
 
 
 			// Camera Orientation 1 - default look at

+ 12 - 19
examples/webgl_geometry_large_mesh.html

@@ -111,25 +111,19 @@
 
 				// LIGHTS
 
-				var ambient = new THREE.AmbientLight( 0x101010 );
-				scene.add( ambient );
-
 				directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
 				directionalLight.position.set( 1, 1, 2 ).normalize();
 				scene.add( directionalLight );
 
-				pointLight = new THREE.PointLight( 0xffaa00 );
-				pointLight.position.set( 0, 0, 0 );
+				pointLight = new THREE.PointLight( 0xffffff, 3, 1000 );
 				scene.add( pointLight );
 
 				// light representation
 
-				sphere = new THREE.SphereGeometry( 100, 16, 8, 1 );
-				lightMesh = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color: 0xffaa00 } ) );
-				lightMesh.scale.set( 0.05, 0.05, 0.05 );
-				lightMesh.position = pointLight.position;
-				scene.add( lightMesh );
+				sphere = new THREE.SphereGeometry( 10, 16, 8, 1 );
 
+				lightMesh = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
+				scene.add( lightMesh );
 
 				if ( render_gl ) {
 					try {
@@ -164,12 +158,10 @@
 				bwebgl.addEventListener( "click", toggleWebGL, false );
 
 				loader = new THREE.BinaryLoader( true );
-				//loader = new THREE.JSONLoader( true );
 				document.body.appendChild( loader.statusDomElement );
 
 				var start = Date.now();
 
-				//loader.load( 'obj/lucy/Lucy100k_slim.js', callback );
 				loader.load( 'obj/lucy/Lucy100k_bin.js', function ( geometry, materials ) {
 
 					addMesh( geometry, 0.75, 900, 0, 0,  0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0x030303, specular: 0x990000, shininess: 30 } ) );
@@ -223,19 +215,20 @@
 
 			}
 
-			var r = 0;
-
 			function render() {
+			
+				var time = Date.now() * 0.001;
 
-				camera.position.x += ( mouseX - camera.position.x ) * .05;
-				camera.position.y += ( - mouseY - camera.position.y ) * .05;
+				camera.position.x += ( mouseX - camera.position.x ) * 0.05;
+				camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
 
 				camera.lookAt( scene.position );
 
-				lightMesh.position.x = 700 * Math.cos( r );
-				lightMesh.position.z = 700 * Math.sin( r );
+				pointLight.position.x = 600 * Math.cos( time );
+				pointLight.position.y = 400 * Math.cos( time * 1.25 );
+				pointLight.position.z = 300 * Math.sin( time );
 
-				r += 0.01;
+				lightMesh.position.copy( pointLight.position );
 
 				if ( render_canvas ) canvasRenderer.render( scene, camera );
 				if ( render_gl && has_gl ) webglRenderer.render( scene, camera );

+ 25 - 33
examples/webgl_geometry_minecraft_ao.html

@@ -167,9 +167,11 @@
 
 						var h = getY( x, z );
 
-						dummy.position.x = x * 100 - worldHalfWidth * 100;
-						dummy.position.y = h * 100;
-						dummy.position.z = z * 100 - worldHalfDepth * 100;
+						matrix.makeTranslation(
+							x * 100 - worldHalfWidth * 100,
+							h * 100,
+							z * 100 - worldHalfDepth * 100
+						);
 
 						var px = getY( x + 1, z );
 						var nx = getY( x - 1, z );
@@ -188,93 +190,83 @@
 
 						if ( a + c > b + d ) {
 
-							dummy.geometry = py2Geometry;
-
-							var colors = dummy.geometry.faces[ 0 ].vertexColors;
+							var colors = py2Geometry.faces[ 0 ].vertexColors;
 							colors[ 0 ] = b === 0 ? shadow : light;
 							colors[ 1 ] = c === 0 ? shadow : light;
 							colors[ 2 ] = a === 0 ? shadow : light;
 
-							var colors = dummy.geometry.faces[ 1 ].vertexColors;
+							var colors = py2Geometry.faces[ 1 ].vertexColors;
 							colors[ 0 ] = c === 0 ? shadow : light;
 							colors[ 1 ] = d === 0 ? shadow : light;
 							colors[ 2 ] = a === 0 ? shadow : light;
+							
+							geometry.merge( py2Geometry, matrix );
 
 						} else {
 
-							dummy.geometry = pyGeometry;
-
-							var colors = dummy.geometry.faces[ 0 ].vertexColors;
+							var colors = pyGeometry.faces[ 0 ].vertexColors;
 							colors[ 0 ] = a === 0 ? shadow : light;
 							colors[ 1 ] = b === 0 ? shadow : light;
 							colors[ 2 ] = d === 0 ? shadow : light;
 
-							var colors = dummy.geometry.faces[ 1 ].vertexColors;
+							var colors = pyGeometry.faces[ 1 ].vertexColors;
 							colors[ 0 ] = b === 0 ? shadow : light;
 							colors[ 1 ] = c === 0 ? shadow : light;
 							colors[ 2 ] = d === 0 ? shadow : light;
+							
+							geometry.merge( pyGeometry, matrix );
 
 						}
 
-						THREE.GeometryUtils.merge( geometry, dummy );
-
 						if ( ( px != h && px != h + 1 ) || x == 0 ) {
 
-							dummy.geometry = pxGeometry;
-
-							var colors = dummy.geometry.faces[ 0 ].vertexColors;
+							var colors = pxGeometry.faces[ 0 ].vertexColors;
 							colors[ 0 ] = pxpz > px && x > 0 ? shadow : light;
 							colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;
 
-							var colors = dummy.geometry.faces[ 1 ].vertexColors;
+							var colors = pxGeometry.faces[ 1 ].vertexColors;
 							colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;
 
-							THREE.GeometryUtils.merge( geometry, dummy );
+							geometry.merge( pxGeometry, matrix );
 
 						}
 
 						if ( ( nx != h && nx != h + 1 ) || x == worldWidth - 1 ) {
 
-							dummy.geometry = nxGeometry;
-
-							var colors = dummy.geometry.faces[ 0 ].vertexColors;
+							var colors = nxGeometry.faces[ 0 ].vertexColors;
 							colors[ 0 ] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
 							colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;
 
-							var colors = dummy.geometry.faces[ 1 ].vertexColors;
+							var colors = nxGeometry.faces[ 1 ].vertexColors;
 							colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;
 
-							THREE.GeometryUtils.merge( geometry, dummy );
+							geometry.merge( nxGeometry, matrix );
 
 						}
 
 						if ( ( pz != h && pz != h + 1 ) || z == worldDepth - 1 ) {
 
-							dummy.geometry = pzGeometry;
-
-							var colors = dummy.geometry.faces[ 0 ].vertexColors;
+							var colors = pzGeometry.faces[ 0 ].vertexColors;
 							colors[ 0 ] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
 							colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;
 
-							var colors = dummy.geometry.faces[ 1 ].vertexColors;
+							var colors = pzGeometry.faces[ 1 ].vertexColors;
 							colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;
 
-							THREE.GeometryUtils.merge( geometry, dummy );
+							geometry.merge( pzGeometry, matrix );
 
 						}
 
 						if ( ( nz != h && nz != h + 1 ) || z == 0 ) {
 
-							dummy.geometry = nzGeometry;
-
-							var colors = dummy.geometry.faces[ 0 ].vertexColors;
+							var colors = nzGeometry.faces[ 0 ].vertexColors;
 							colors[ 0 ] = pxnz > nz && z > 0 ? shadow : light;
 							colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;
 
-							var colors = dummy.geometry.faces[ 1 ].vertexColors;
+							var colors = nzGeometry.faces[ 1 ].vertexColors;
 							colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;
 
-							THREE.GeometryUtils.merge( geometry, dummy );
+							geometry.merge( nzGeometry, matrix );
 
 						}
 

+ 3 - 8
examples/webgl_geometry_shapes.html

@@ -14,13 +14,10 @@
 		</style>
 	</head>
 	<body>
-		<canvas id="debug" style="position:absolute; left:100px"></canvas>
 
 		<script src="../build/three.min.js"></script>
-
 		<script src="js/libs/stats.min.js"></script>
 
-
 		<script>
 
 			var container, stats;
@@ -111,7 +108,7 @@
 					// vertices from real points
 
 					var pgeo = points.clone();
-					var particles = new THREE.ParticleSystem( pgeo, new THREE.ParticleSystemMaterial( { color: color, size: 2, opacity: 0.75 } ) );
+					var particles = new THREE.PointCloud( pgeo, new THREE.PointCloudMaterial( { color: color, size: 2, opacity: 0.75 } ) );
 					particles.position.set( x, y, z + 75 );
 					particles.rotation.set( rx, ry, rz );
 					particles.scale.set( s, s, s );
@@ -128,7 +125,7 @@
 					// equidistance sampled points
 
 					var pgeo = spacedPoints.clone();
-					var particles2 = new THREE.ParticleSystem( pgeo, new THREE.ParticleSystemMaterial( { color: color, size: 2, opacity: 0.5 } ) );
+					var particles2 = new THREE.PointCloud( pgeo, new THREE.PointCloudMaterial( { color: color, size: 2, opacity: 0.5 } ) );
 					particles2.position.set( x, y, z + 125 );
 					particles2.rotation.set( rx, ry, rz );
 					particles2.scale.set( s, s, s );
@@ -314,12 +311,10 @@
 				splinepts.push( new THREE.Vector2 ( -140, 350 ) );
 				splinepts.push( new THREE.Vector2 ( 0, 0 ) );
 
-				var splineShape = new THREE.Shape(  );
+				var splineShape = new THREE.Shape();
 				splineShape.moveTo( 0, 0 );
 				splineShape.splineThru( splinepts );
 
-				// splineShape.debug( document.getElementById("debug") );
-
 				// TODO 3d path?
 
 				var apath = new THREE.SplineCurve3();

+ 16 - 16
examples/webgl_gpgpu_birds.html

@@ -35,7 +35,7 @@
 			<a href="http://threejs.org" target="_blank">three.js</a> - <span id="birds"></span> webgl gpgpu birds<br/>
 			Select <span id="options"></span> birds<br/>
 			Move mouse to disturb birds.
-			
+
 		</div>
 
 		<script src="../build/three.min.js"></script>
@@ -122,7 +122,7 @@
 			uniform float delta; // about 0.016
 			uniform float seperationDistance; // 20
 			uniform float alignmentDistance; // 40
-			uniform float cohesionDistance; // 
+			uniform float cohesionDistance; //
 			uniform float freedomFactor;
 			uniform vec3 predator;
 
@@ -189,7 +189,7 @@
 				float preyRadius = 150.0;
 				float preyRadiusSq = preyRadius * preyRadius;
 
-				
+
 				// move birds away from predator
 				if (dist < preyRadius) {
 
@@ -240,7 +240,7 @@
 								float adjustedPercent = ( percent - separationThresh ) / threshDelta;
 
 								birdVelocity = texture2D( textureVelocity, vec2(x/resolution.x, y/resolution.y) ).xyz;
-								
+
 								f = ( 0.5 - cos( adjustedPercent * PI_2 ) * 0.5 + 0.5 ) * delta;
 								velocity += normalize(birdVelocity) * f;
 
@@ -262,7 +262,7 @@
 
 				}
 
-				
+
 
 				// this make tends to fly around than down or up
 				// if (velocity.y > 0.) velocity.y *= (1. - 0.2 * delta);
@@ -284,7 +284,7 @@
 			attribute float birdVertex;
 
 			attribute vec3 birdColor;
-			
+
 			uniform sampler2D texturePosition;
 			uniform sampler2D textureVelocity;
 
@@ -313,7 +313,7 @@
 				float xz = length( velocity.xz );
 				float xyz = 1.;
 				float x = sqrt( 1. - velocity.y * velocity.y );
-				
+
 				float cosry = velocity.x / xz;
 				float sinry = velocity.z / xz;
 
@@ -337,7 +337,7 @@
 				newPosition += pos;
 
 				z = newPosition.z;
-				
+
 				vColor = vec4( birdColor, 1.0 );
 				gl_Position = projectionMatrix *  viewMatrix  * vec4( newPosition, 1.0 );
 			}
@@ -370,7 +370,7 @@
 			if (hash) hash = parseInt(hash, 0);
 
 			/* TEXTURE WIDTH FOR SIMULATION */
-			var WIDTH = hash || 32; 
+			var WIDTH = hash || 32;
 
 			var BIRDS = WIDTH * WIDTH;
 
@@ -382,10 +382,10 @@
 
 				THREE.BufferGeometry.call( this );
 
-				var vertices = new THREE.Float32Attribute( points * 3, 3 );
-				var birdColors = new THREE.Float32Attribute( points * 3, 3 );
-				var references = new THREE.Float32Attribute( points * 2, 2 );
-				var birdVertex = new THREE.Float32Attribute( points, 1 );
+				var vertices = new THREE.BufferAttribute( new Float32Array( points * 3 ), 3 );
+				var birdColors = new THREE.BufferAttribute( new Float32Array( points * 3 ), 3 );
+				var references = new THREE.BufferAttribute( new Float32Array( points * 2 ), 2 );
+				var birdVertex = new THREE.BufferAttribute( new Float32Array( points ), 1 );
 
 				this.addAttribute( 'position', vertices );
 				this.addAttribute( 'birdColor', birdColors );
@@ -465,7 +465,7 @@
 
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
-			
+
 			var PARTICLES = WIDTH * WIDTH;
 			var BOUNDS = 800, BOUNDS_HALF = BOUNDS / 2;
 
@@ -555,7 +555,7 @@
 				gui.close();
 
 				initBirds();
-				
+
 			}
 
 
@@ -594,7 +594,7 @@
 				});
 
 
-				// var 
+				// var
 				birdMesh = new THREE.Mesh( geometry, shaderMaterial );
 				birdMesh.rotation.y = Math.PI / 2;
 				birdMesh.matrixAutoUpdate = false;

+ 18 - 24
examples/webgl_interactive_cubes_gpu.html

@@ -104,51 +104,43 @@
 
 				}
 
+				var geom = new THREE.BoxGeometry( 1, 1, 1 );
+				var color = new THREE.Color();
+
+				var matrix = new THREE.Matrix4();
+				var quaternion = new THREE.Quaternion();
+
 				for ( var i = 0; i < 5000; i ++ ) {
 
 					var position = new THREE.Vector3();
-
 					position.x = Math.random() * 10000 - 5000;
 					position.y = Math.random() * 6000 - 3000;
 					position.z = Math.random() * 8000 - 4000;
 
 					var rotation = new THREE.Euler();
-
 					rotation.x = Math.random() * 2 * Math.PI;
 					rotation.y = Math.random() * 2 * Math.PI;
 					rotation.z = Math.random() * 2 * Math.PI;
 
 					var scale = new THREE.Vector3();
-
 					scale.x = Math.random() * 200 + 100;
 					scale.y = Math.random() * 200 + 100;
 					scale.z = Math.random() * 200 + 100;
 
-					// give the geom's vertices a random color, to be displayed
-
-					var geom = new THREE.BoxGeometry( 1, 1, 1 );
-					var color = new THREE.Color( Math.random() * 0xffffff );
-					applyVertexColors( geom, color );
+					quaternion.setFromEuler( rotation, false );
+					matrix.compose( position, quaternion, scale );
 
-					var cube = new THREE.Mesh( geom );
-					cube.position.copy( position );
-					cube.rotation.copy( rotation );
-					cube.scale.copy( scale );
+					// give the geom's vertices a random color, to be displayed
 
-					THREE.GeometryUtils.merge( geometry, cube );
+					applyVertexColors( geom, color.setHex( Math.random() * 0xffffff ) );
 
-					//give the pickingGeom's vertices a color corresponding to the "id"
+					geometry.merge( geom, matrix );
 
-					var pickingGeom = new THREE.BoxGeometry( 1, 1, 1 );
-					var pickingColor = new THREE.Color( i );
-					applyVertexColors( pickingGeom, pickingColor );
+					// give the geom's vertices a color corresponding to the "id"
 
-					var pickingCube = new THREE.Mesh( pickingGeom );
-					pickingCube.position.copy( position );
-					pickingCube.rotation.copy( rotation );
-					pickingCube.scale.copy( scale );
+					applyVertexColors( geom, color.setHex( i ) );
 
-					THREE.GeometryUtils.merge( pickingGeometry, pickingCube );
+					pickingGeometry.merge( geom, matrix );
 
 					pickingData[ i ] = {
 
@@ -165,7 +157,10 @@
 
 				pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );
 
-				highlightBox = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), new THREE.MeshLambertMaterial( { color: 0xffff00 } ) );
+				highlightBox = new THREE.Mesh(
+					new THREE.BoxGeometry( 1, 1, 1 ),
+					new THREE.MeshLambertMaterial( { color: 0xffff00 }
+				) );
 				scene.add( highlightBox );
 
 				projector = new THREE.Projector();
@@ -174,7 +169,6 @@
 				renderer.setClearColor( 0xffffff, 1 );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.sortObjects = false;
-
 				container.appendChild( renderer.domElement );
 
 				stats = new Stats();

+ 366 - 0
examples/webgl_interactive_raycasting_pointcloud.html

@@ -0,0 +1,366 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - interactive - raycasting - pointcloud</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #ffffff;
+				background-color: #000000;
+				margin: 0px;
+				overflow: hidden;
+			}
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				padding: 5px;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+				font-weight: bold;
+			}
+			a {
+				color: #fff;
+			}
+		</style>
+	</head>
+
+	<body>
+		<div id="container"></div>
+		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> webgl - interactive - raycasting - pointcloud </div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var renderer, scene, camera, stats;
+			var pointclouds;
+			var projector, raycaster, intersects;
+			var mouse = { x: 1, y: 1 };
+			var vector = new THREE.Vector3();
+			var intersection = null;
+			var spheres = [];
+			var spheresIndex = 0;
+			var clock;
+			
+			var threshold = 0.1;
+			var pointSize = 0.01;
+			var width = 150;
+			var length = 150;
+			var rotateY = new THREE.Matrix4().makeRotationY( 0.005 );
+
+			init();
+			animate();
+			
+			function generatePointCloudGeometry( color, width, length ){
+			
+				var geometry = new THREE.BufferGeometry();
+				var numPoints = width*length;
+				
+				var positions = new Float32Array( numPoints*3 );
+				var colors = new Float32Array( numPoints*3 );
+				
+				var k = 0;
+
+				for( var i = 0; i < width; i++ ) {
+
+					for( var j = 0; j < length; j++ ) {
+
+						var u = i / width;
+						var v = j / length;
+						var x = u - 0.5;
+						var y = ( Math.cos( u * Math.PI * 8 ) + Math.sin( v * Math.PI * 8 ) ) / 20;
+						var z = v - 0.5;
+						
+						positions[ 3 * k ] = x;
+						positions[ 3 * k + 1 ] = y;
+						positions[ 3 * k + 2 ] = z;
+						
+						var intensity = ( y + 0.1 ) * 5;
+						colors[ 3 * k ] = color.r * intensity;
+						colors[ 3 * k + 1 ] = color.g * intensity;
+						colors[ 3 * k + 2 ] = color.b * intensity;
+
+						k++;
+
+					}
+
+				}
+				
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
+				geometry.computeBoundingBox();
+				
+				return geometry;
+			
+			}
+			
+			function generatePointcloud( color, width, length ) {
+			
+				var geometry = generatePointCloudGeometry( color, width, length );
+				
+				var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: true } );
+				var pointcloud = new THREE.PointCloud( geometry, material );
+				
+				return pointcloud;
+				
+			}
+			
+			function generateIndexedPointcloud( color, width, length ) {
+			
+				var geometry = generatePointCloudGeometry( color, width, length );
+				var numPoints = width * length;
+				var indices = new Uint16Array( numPoints );
+				
+				var k = 0;
+
+				for( var i = 0; i < width; i++ ) {
+
+					for( var j = 0; j < length; j++ ) {
+
+						indices[ k ] = k;
+						k++;
+
+					}
+
+				}
+				
+				geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+				
+				var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: true } );
+				var pointcloud = new THREE.PointCloud( geometry, material );
+				
+				return pointcloud;
+				
+			}
+			
+			function generateIndexedWithOffsetPointcloud( color, width, length ){
+			
+				var geometry = generatePointCloudGeometry( color, width, length );
+				var numPoints = width * length;
+				var indices = new Uint16Array( numPoints );
+				
+				var k = 0;
+
+				for( var i = 0; i < width; i++ ){
+
+					for( var j = 0; j < length; j++ ) {
+
+						indices[ k ] = k;
+						k++;
+
+					}
+
+				}
+				
+				geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
+				
+				var offset = { start: 0, count: indices.length, index: 0 };
+				geometry.offsets.push( offset );
+				
+				var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: true } );
+				var pointcloud = new THREE.PointCloud( geometry, material );
+				
+				return pointcloud;
+			
+			}
+			
+			function generateRegularPointcloud( color, width, length ) {
+			
+				var geometry = new THREE.Geometry();
+				var numPoints = width * length;
+				
+				var colors = [];
+				
+				var k = 0;
+
+				for( var i = 0; i < width; i++ ) {
+
+					for( var j = 0; j < length; j++ ) {
+
+						var u = i / width;
+						var v = j / length;
+						var x = u - 0.5;
+						var y = ( Math.cos( u * Math.PI * 8 ) + Math.sin( v * Math.PI * 8) ) / 20;
+						var z = v - 0.5;	
+						var v = new THREE.Vector3( x,y,z );
+						
+						var intensity = ( y + 0.1 ) * 7;
+						colors[ 3 * k ] = color.r * intensity;
+						colors[ 3 * k + 1 ] = color.g * intensity;
+						colors[ 3 * k + 2 ] = color.b * intensity;
+						
+						geometry.vertices.push( v );
+						colors[ k ] = ( color.clone().multiplyScalar( intensity ) );
+						
+						k++;
+
+					}
+
+				}
+				
+				geometry.colors = colors;
+				geometry.computeBoundingBox();
+				
+				var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: true } );
+				var pointcloud = new THREE.PointCloud( geometry, material );
+				
+				return pointcloud;
+			
+			}
+
+			function init() {
+
+				container = document.getElementById( 'container' );
+
+				scene = new THREE.Scene();
+				
+				clock = new THREE.Clock();
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
+				camera.applyMatrix( new THREE.Matrix4().makeTranslation( 0,0,20 ) );
+				camera.applyMatrix( new THREE.Matrix4().makeRotationX( -0.5 ) );
+
+				//
+
+				pcBuffer = generatePointcloud( new THREE.Color( 1,0,0 ), width, length );
+				pcBuffer.scale.set( 10,10,10 );
+				pcBuffer.position.set( -5,0,5 );
+				scene.add( pcBuffer );
+					
+				var pcIndexed = generateIndexedPointcloud( new THREE.Color( 0,1,0 ), width, length );
+				pcIndexed.scale.set( 10,10,10 );
+				pcIndexed.position.set( 5,0,5 );
+				scene.add( pcIndexed );
+			
+				var pcIndexedOffset = generateIndexedWithOffsetPointcloud( new THREE.Color( 0,1,1 ), width, length );
+				pcIndexedOffset.scale.set( 10,10,10 );
+				pcIndexedOffset.position.set( 5,0,-5 );
+				scene.add( pcIndexedOffset );
+				
+				var pcRegular = generateRegularPointcloud( new THREE.Color( 1,0,1 ), width, length );
+				pcRegular.scale.set( 10,10,10 );
+				pcRegular.position.set( -5,0,-5 );
+				scene.add( pcRegular );
+
+				pointclouds = [ pcBuffer, pcIndexed, pcIndexedOffset, pcRegular ];
+				
+				//
+				
+				var sphereGeometry = new THREE.SphereGeometry( 0.1, 32, 32 );
+				var sphereMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, shading: THREE.FlatShading } );
+				
+				for ( var i = 0; i < 40; i++ ) { 
+				
+					var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
+					scene.add( sphere );
+					spheres.push( sphere );
+				
+				}
+
+				//
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				container.appendChild( renderer.domElement );
+
+				//
+
+				projector = new THREE.Projector();
+				raycaster = new THREE.Raycaster();
+				raycaster.params.PointCloud.threshold = threshold;
+
+				//
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+			
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				event.preventDefault();
+
+				mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
+				mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+			
+			var toggle = 0;
+			
+			function render() { 
+			
+				camera.applyMatrix( rotateY );
+				camera.updateMatrixWorld( true );
+				
+				vector.set( mouse.x, mouse.y, 0.1 );
+
+				projector.unprojectVector( vector, camera );
+
+				raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() );
+				
+				var intersections = raycaster.intersectObjects( pointclouds );
+				intersection = ( intersections.length ) > 0 ? intersections[ 0 ] : null;
+				
+				if ( toggle > 0.02 && intersection !== null) {
+				
+					spheres[ spheresIndex ].position.copy( intersection.point );
+					spheres[ spheresIndex ].scale.set( 1, 1, 1 );
+					spheresIndex = ( spheresIndex + 1 ) % spheres.length;
+					
+					toggle = 0;
+				
+				}
+				
+				for ( var i = 0; i < spheres.length; i++ ) {
+					
+					var sphere = spheres[ i ];
+					sphere.scale.multiplyScalar( 0.98 );
+					sphere.scale.clampScalar( 0.01, 1 );
+				
+				}
+				
+				toggle += clock.getDelta();
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+
+</html>

+ 1 - 1
examples/webgl_interactive_voxelpainter.html

@@ -288,7 +288,7 @@
 					if ( intersector ) {
 
 						setVoxelPosition( intersector );
-						rollOverMesh.position = voxelPosition;
+						rollOverMesh.position.copy( voxelPosition );
 
 					}
 

+ 12 - 11
examples/webgl_kinect.html

@@ -92,7 +92,7 @@
 			void main() {
 
 				vec4 color = texture2D( map, vUv );
-				gl_FragColor = vec4( color.r, color.g, color.b, smoothstep( 8000.0, -8000.0, gl_FragCoord.z / gl_FragCoord.w ) );
+				gl_FragColor = vec4( color.r, color.g, color.b, 0.2 );
 
 			}
 
@@ -146,22 +146,24 @@
 				video.addEventListener( 'loadedmetadata', function ( event ) {
 
 					texture = new THREE.Texture( video );
-
+					texture.generateMipmaps = false;
+					
 					var width = 640, height = 480;
 					var nearClipping = 850, farClipping = 4000;
 
-					geometry = new THREE.Geometry();
+					geometry = new THREE.BufferGeometry();
 
-					for ( var i = 0, l = width * height; i < l; i ++ ) {
+					var vertices = new Float32Array( width * height * 3 );
 
-						var vertex = new THREE.Vector3();
-						vertex.x = ( i % width );
-						vertex.y = Math.floor( i / width );
+					for ( var i = 0, j = 0, l = vertices.length; i < l; i += 3, j ++ ) {
 
-						geometry.vertices.push( vertex );
+						vertices[ i ] = j % width;
+						vertices[ i + 1 ] = Math.floor( j / width );
 
 					}
 
+					geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+
 					material = new THREE.ShaderMaterial( {
 
 						uniforms: {
@@ -178,14 +180,13 @@
 						},
 						vertexShader: document.getElementById( 'vs' ).textContent,
 						fragmentShader: document.getElementById( 'fs' ).textContent,
+						blending: THREE.AdditiveBlending,
 						depthTest: false, depthWrite: false,
 						transparent: true
 
 					} );
 
-					mesh = new THREE.ParticleSystem( geometry, material );
-					mesh.position.x = 0;
-					mesh.position.y = 0;
+					mesh = new THREE.PointCloud( geometry, material );
 					scene.add( mesh );
 
 					setInterval( function () {

+ 1 - 1
examples/webgl_lensflares.html

@@ -161,7 +161,7 @@
 					lensFlare.add( textureFlare3, 70, 1.0, THREE.AdditiveBlending );
 
 					lensFlare.customUpdateCallback = lensFlareUpdateCallback;
-					lensFlare.position = light.position;
+					lensFlare.position.copy( light.position );
 
 					scene.add( lensFlare );
 

+ 3 - 0
examples/webgl_loader_json_objconverter.html

@@ -36,6 +36,7 @@
 		</div>
 
 		<script src="../build/three.min.js"></script>
+		<script src="js/loaders/DDSLoader.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
@@ -182,6 +183,8 @@
 				bcanvas.addEventListener("click", toggleCanvas, false);
 				bwebgl.addEventListener("click", toggleWebGL, false);
 
+				THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
+
 				var loader = new THREE.JSONLoader();
 				var callbackMale = function ( geometry, materials ) { createScene( geometry, materials, 90, FLOOR, 50, 105 ) };
 				var callbackFemale = function ( geometry, materials ) { createScene( geometry, materials, -80, FLOOR, 50, 0 ) };

+ 3 - 0
examples/webgl_loader_obj_mtl.html

@@ -32,6 +32,7 @@
 
 		<script src="../build/three.min.js"></script>
 
+		<script src="js/loaders/DDSLoader.js"></script>
 		<script src="js/loaders/MTLLoader.js"></script>
 		<script src="js/loaders/OBJMTLLoader.js"></script>
 
@@ -75,6 +76,8 @@
 
 				// model
 
+				THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
+
 				var loader = new THREE.OBJMTLLoader();
 				loader.load( 'obj/male02/male02.obj', 'obj/male02/male02_dds.mtl', function ( object ) {
 

+ 4 - 0
examples/webgl_loader_scene.html

@@ -149,6 +149,8 @@
 
 		<script src="../build/three.min.js"></script>
 
+		<script src="js/loaders/DDSLoader.js"></script>
+
 		<script src="js/loaders/ctm/lzma.js"></script>
 		<script src="js/loaders/ctm/ctm.js"></script>
 		<script src="js/loaders/ctm/CTMLoader.js"></script>
@@ -342,6 +344,8 @@
 
 				$( "progress" ).style.display = "block";
 
+				THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
+
 				var loader = new THREE.SceneLoader();
 
 				loader.addGeometryHandler( "binary", THREE.BinaryLoader );

+ 21 - 14
examples/webgl_materials_texture_compressed.html

@@ -38,6 +38,7 @@
 		</div>
 
 		<script src="../build/three.min.js"></script>
+		<script src="js/loaders/DDSLoader.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
@@ -68,44 +69,50 @@
 				DXT3 - RGBA - transparent textures with sharp alpha transitions
 				DXT5 - RGBA - transparent textures with full alpha range
 				*/
+
+				var loader = new THREE.DDSLoader();
 											
-				var map1 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/disturb_dxt1_nomip.dds' );
+				var map1 = loader.load( 'textures/compressed/disturb_dxt1_nomip.dds' );
 				map1.minFilter = map1.magFilter = THREE.LinearFilter;
 				map1.anisotropy = 4;
 
-				var map2 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/disturb_dxt1_mip.dds' );
+				var map2 = loader.load( 'textures/compressed/disturb_dxt1_mip.dds' );
 				map2.anisotropy = 4;
 
-				var map3 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/hepatica_dxt3_mip.dds' );
+				var map3 = loader.load( 'textures/compressed/hepatica_dxt3_mip.dds' );
 				map3.anisotropy = 4;
 
-				var map4 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/explosion_dxt5_mip.dds' );
+				var map4 = loader.load( 'textures/compressed/explosion_dxt5_mip.dds' );
 				map4.anisotropy = 4;
 
-				var map5 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/disturb_argb_nomip.dds' );
+				var map5 = loader.load( 'textures/compressed/disturb_argb_nomip.dds' );
 				map5.minFilter = map5.magFilter = THREE.LinearFilter;
 				map5.anisotropy = 4;
 
-				var map6 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/disturb_argb_mip.dds' );
+				var map6 = loader.load( 'textures/compressed/disturb_argb_mip.dds' );
 				map6.anisotropy = 4;
 
-				var cubemap1 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/Mountains.dds', new THREE.CubeReflectionMapping, function( cubemap ) {
-					cubemap1.magFilter = cubemap1.minFilter = THREE.LinearFilter;
+				var cubemap1 = loader.load( 'textures/compressed/Mountains.dds', function ( texture ) {
+					texture.magFilter = THREE.LinearFilter
+					texture.minFilter = THREE.LinearFilter;
+					texture.mapping = new THREE.CubeReflectionMapping();
 					material1.needsUpdate = true;
-
 				} );
 
-				var cubemap2 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/Mountains_argb_mip.dds', new THREE.CubeReflectionMapping, function( cubemap ) {
-					cubemap2.magFilter = cubemap2.minFilter = THREE.LinearFilter;
+				var cubemap2 = loader.load( 'textures/compressed/Mountains_argb_mip.dds', function ( texture ) {
+					texture.magFilter = THREE.LinearFilter;
+					texture.minFilter = THREE.LinearFilter;
+					texture.mapping = new THREE.CubeReflectionMapping();
 					material5.needsUpdate = true;
 				} );
 
-				var cubemap3 = THREE.ImageUtils.loadDDSTexture( 'textures/compressed/Mountains_argb_nomip.dds', new THREE.CubeReflectionMapping, function( cubemap ) {
-					cubemap3.magFilter = cubemap3.minFilter = THREE.LinearFilter;
+				var cubemap3 = loader.load( 'textures/compressed/Mountains_argb_nomip.dds', function ( texture ) {
+					texture.magFilter = THREE.LinearFilter;
+					texture.minFilter = THREE.LinearFilter;
+					texture.mapping = new THREE.CubeReflectionMapping();
 					material6.needsUpdate = true;
 				} );
 
-
 				var material1 = new THREE.MeshBasicMaterial( { map: map1, envMap: cubemap1 } );
 				var material2 = new THREE.MeshBasicMaterial( { map: map2 } );
 				var material3 = new THREE.MeshBasicMaterial( { map: map3, alphaTest: 0.5, side: THREE.DoubleSide } );

+ 148 - 0
examples/webgl_materials_texture_tga.html

@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<!--
+@author Daosheng Mu / https://github.com/DaoshengMu/
+-->
+<html>
+	<head>
+		<title>three.js webgl - materials - tga texture</title>
+		<meta charset="UTF-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #000;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+
+				background-color: #fff;
+				margin: 0px;
+				padding: 0px;
+				overflow: hidden;
+			}
+				
+			#stats { position: absolute; top:0; left: 0 }
+			#stats #fps { background: transparent !important }
+			#stats #fps #fpsText { color: #777 !important }
+			#stats #fps #fpsGraph { display: none }
+		</style>
+	</head>
+	<body>
+		<div id="info">
+				<a href="http://threejs.org" target="_blank">three.js</a> - tga texture example
+		</div>
+		<script src="../build/three.min.js"></script>
+		<script src="js/loaders/TGALoader.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+		
+		<script>
+			
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var SCREEN_WIDTH = window.innerWidth;
+			var SCREEN_HEIGHT = window.innerHeight;
+
+			var container,stats;
+
+			var camera, scene, renderer;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+				 
+			init();
+			animate();
+			
+			function init() {
+				
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+				
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				
+				camera = new THREE.PerspectiveCamera( 35, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 25000 );
+				camera.position.z = 200;
+
+				scene = new THREE.Scene();
+				
+				var light = new THREE.DirectionalLight( 0xffffff, 2 );
+				light.position.set( 1, 1, 1 );
+				scene.add( light );
+				
+				var loader = new THREE.TGALoader();
+
+				// add box 1 - grey8 texture
+				var texture1 = loader.load( 'textures/crate_grey8.tga' );
+				var material1 = new THREE.MeshPhongMaterial( { color: 0xffffff, map: texture1 } );
+				
+				var geometry = new THREE.BoxGeometry( 50, 50, 50 );
+				var mesh1 = new THREE.Mesh( geometry, material1 );
+				mesh1.rotation.x = -Math.PI / 2;
+				mesh1.position.x = - 50;
+				
+				scene.add( mesh1 );
+				
+				// add box 2 - tga texture
+				var texture2 = loader.load( 'textures/crate_color8.tga' );
+				var material2 = new THREE.MeshPhongMaterial( { color: 0xffffff, map: texture2 } );
+					   
+				var mesh2 = new THREE.Mesh( geometry, material2 );
+				mesh2.rotation.x = -Math.PI / 2;
+				mesh2.position.x = 50;
+				
+				scene.add( mesh2 );
+				
+				// RENDERER
+				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+				renderer.setClearColor( 0xf2f7ff, 1 );
+				renderer.autoClear = false;
+
+				renderer.domElement.style.position = "relative";
+				container.appendChild( renderer.domElement );
+
+				// STATS1
+				stats = new Stats();
+				container.appendChild( stats.domElement );
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+			}
+			
+			function onDocumentMouseMove(event) {
+
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
+
+			}
+
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * .05;
+				camera.position.y = THREE.Math.clamp( camera.position.y + ( - ( mouseY - 200 ) - camera.position.y ) * .05, 50, 1000 );
+
+				camera.lookAt( scene.position );
+
+				renderer.enableScissorTest( false );
+				renderer.clear();
+				renderer.enableScissorTest( true );
+
+				renderer.setScissor( 0, 0, SCREEN_WIDTH - 2, SCREEN_HEIGHT );
+				renderer.render( scene, camera );
+					
+			}
+			
+		</script>
+	</body>
+</html>

+ 1 - 2
examples/webgl_panorama_equirectangular.html

@@ -41,8 +41,7 @@
 
 			var camera, scene, renderer;
 
-			var texture_placeholder,
-			isUserInteracting = false,
+			var isUserInteracting = false,
 			onMouseDownMouseX = 0, onMouseDownMouseY = 0,
 			lon = 0, onMouseDownLon = 0,
 			lat = 0, onMouseDownLat = 0,

+ 3 - 52
src/Three.js

@@ -1,64 +1,15 @@
 /**
  * @author mrdoob / http://mrdoob.com/
- * @author Larry Battle / http://bateru.com/news
- * @author bhouston / http://exocortex.com
  */
 
 var THREE = { REVISION: '68dev' };
 
 // browserify support
-if (typeof module === 'object') {
-	module.exports = THREE;
-}
-
-self.console = self.console || {
-
-	info: function () {},
-	log: function () {},
-	debug: function () {},
-	warn: function () {},
-	error: function () {}
-
-};
-
-// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
-// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
-
-// requestAnimationFrame polyfill by Erik Möller
-// fixes from Paul Irish and Tino Zijdel
-// using 'self' instead of 'window' for compatibility with both NodeJS and IE10.
-( function () {
-
-	var lastTime = 0;
-	var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
-
-	for ( var x = 0; x < vendors.length && !self.requestAnimationFrame; ++ x ) {
-
-		self.requestAnimationFrame = self[ vendors[ x ] + 'RequestAnimationFrame' ];
-		self.cancelAnimationFrame = self[ vendors[ x ] + 'CancelAnimationFrame' ] || self[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
+if ( typeof module === 'object' ) {
 
-	}
-
-	if ( self.requestAnimationFrame === undefined && self['setTimeout'] !== undefined ) {
-
-		self.requestAnimationFrame = function ( callback ) {
-
-			var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
-			var id = self.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall );
-			lastTime = currTime + timeToCall;
-			return id;
-
-		};
-
-	}
-
-	if( self.cancelAnimationFrame === undefined && self['clearTimeout'] !== undefined ) {
-
-		self.cancelAnimationFrame = function ( id ) { self.clearTimeout( id ) };
-
-	}
+	module.exports = THREE;
 
-}() );
+}
 
 // GL STATE CONSTANTS
 

+ 0 - 0
src/extras/cameras/CubeCamera.js → src/cameras/CubeCamera.js


+ 9 - 9
src/core/BufferAttribute.js

@@ -93,21 +93,21 @@ THREE.BufferAttribute.prototype = {
 
 THREE.Int8Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Int8Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Int8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };
 
 THREE.Uint8Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Uint8Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Uint8Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };
 
 THREE.Uint8ClampedAttribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Uint8ClampedAttribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 
@@ -115,42 +115,42 @@ THREE.Uint8ClampedAttribute = function ( data, itemSize ) {
 
 THREE.Int16Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Int16Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Int16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };
 
 THREE.Uint16Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Uint16Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Uint16Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };
 
 THREE.Int32Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Int32Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Int32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };
 
 THREE.Uint32Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Uint32Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Uint32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };
 
 THREE.Float32Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Float32Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Float32Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };
 
 THREE.Float64Attribute = function ( data, itemSize ) {
 
-	console.log( 'THREE.Float64Attribute has been DEPRECATED. Use THREE.BufferAttribute( array, itemSize ) instead.' );
+	console.warn( 'THREE.Float64Attribute has been removed. Use THREE.BufferAttribute( array, itemSize ) instead.' );
 	return new THREE.BufferAttribute( data, itemSize );
 
 };

+ 1 - 1
src/core/BufferGeometry.js

@@ -26,7 +26,7 @@ THREE.BufferGeometry.prototype = {
 
 		if ( attribute instanceof THREE.BufferAttribute === false ) {
 
-			console.warn( 'DEPRECATED: BufferGeometry\'s addAttribute() now expects ( name, attribute ).' );
+			console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
 
 			this.attributes[ name ] = { array: arguments[ 1 ], itemSize: arguments[ 2 ] };
 

+ 18 - 5
src/core/Face3.js

@@ -10,7 +10,7 @@ THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
 	this.c = c;
 
 	this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
-	this.vertexNormals = normal instanceof Array ? normal : [ ];
+	this.vertexNormals = normal instanceof Array ? normal : [];
 
 	this.color = color instanceof THREE.Color ? color : new THREE.Color();
 	this.vertexColors = color instanceof Array ? color : [];
@@ -34,10 +34,23 @@ THREE.Face3.prototype = {
 
 		face.materialIndex = this.materialIndex;
 
-		var i, il;
-		for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
-		for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
-		for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
+		for ( var i = 0, il = this.vertexNormals.length; i < il; i ++ ) {
+		
+			face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
+		
+		}
+
+		for ( var i = 0, il = this.vertexColors.length; i < il; i ++ ) {
+		
+			face.vertexColors[ i ] = this.vertexColors[ i ].clone();
+		
+		}
+
+		for ( var i = 0, il = this.vertexTangents.length; i < il; i ++ ) {
+		
+			face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
+		
+		}
 
 		return face;
 

+ 0 - 1
src/core/Face4.js

@@ -5,7 +5,6 @@
 THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {
 
 	console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.')
-
 	return new THREE.Face3( a, b, c, normal, color, materialIndex );
 
 };

+ 54 - 32
src/core/Object3D.js

@@ -15,28 +15,63 @@ THREE.Object3D = function () {
 	this.parent = undefined;
 	this.children = [];
 
-	this.up = new THREE.Vector3( 0, 1, 0 );
-
-	this.position = new THREE.Vector3();
+	this.up = THREE.Object3D.DefaultUp.clone();
 
 	var scope = this;
+	
+	var position = new THREE.Vector3();
+	var rotation = new THREE.Euler();
+	var quaternion = new THREE.Quaternion();
+	var scale = new THREE.Vector3( 1, 1, 1 );
+
+	rotation.onChange( function () {
+		quaternion.setFromEuler( rotation, false );
+	} );
+	
+	quaternion.onChange( function () {
+		rotation.setFromQuaternion( quaternion, undefined, false );
+	} );
 
 	Object.defineProperties( this, {
+		position: {
+			enumerable: true,
+			get: function () {
+				return position;
+			},
+			set: function ( value ) {
+				console.error( 'THREE.Object3D: .position = new THREE.Vector3() pattern no longer works. Use .position.copy() instead.' );
+				position.copy( value );
+			}
+		},
 		rotation: {
 			enumerable: true,
-			value: new THREE.Euler().onChange( function () {
-				scope.quaternion.setFromEuler( scope.rotation, false );
-			} )
+			get: function () {
+				return rotation;
+			},
+			set: function ( value ) {
+				console.error( 'THREE.Object3D: .rotation = new THREE.Euler() pattern no longer works. Use .rotation.copy() instead.' );
+				rotation.copy( value );
+			}
 		},
 		quaternion: {
 			enumerable: true,
-			value: new THREE.Quaternion().onChange( function () {
-				scope.rotation.setFromQuaternion( scope.quaternion, undefined, false );
-			} )
+			get: function () {
+				return quaternion;
+			},
+			set: function ( value ) {
+				console.error( 'THREE.Object3D: .quaternion = new THREE.Quaternion() pattern no longer works. Use .quaternion.copy() instead.' );
+				quaternion.copy( value );
+			}
 		},
 		scale: {
 			enumerable: true,
-			value: new THREE.Vector3( 1, 1, 1 )
+			get: function () {
+				return scale;
+			},
+			set: function ( value ) {
+				console.error( 'THREE.Object3D: .scale = new THREE.Vector3() pattern no longer works. Use .scale.copy() instead.' );
+				scale.copy( value );
+			}
 		}
 	} );
 
@@ -61,6 +96,7 @@ THREE.Object3D = function () {
 
 };
 
+THREE.Object3D.DefaultUp = new THREE.Vector3( 0, 1, 0 );
 
 THREE.Object3D.prototype = {
 
@@ -68,7 +104,7 @@ THREE.Object3D.prototype = {
 
 	get eulerOrder () {
 
-		console.warn( 'DEPRECATED: Object3D\'s .eulerOrder has been moved to Object3D\'s .rotation.order.' );
+		console.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' );
 
 		return this.rotation.order;
 
@@ -76,7 +112,7 @@ THREE.Object3D.prototype = {
 
 	set eulerOrder ( value ) {
 
-		console.warn( 'DEPRECATED: Object3D\'s .eulerOrder has been moved to Object3D\'s .rotation.order.' );
+		console.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' );
 
 		this.rotation.order = value;
 
@@ -84,13 +120,13 @@ THREE.Object3D.prototype = {
 
 	get useQuaternion () {
 
-		console.warn( 'DEPRECATED: Object3D\'s .useQuaternion has been removed. The library now uses quaternions by default.' );
+		console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
 
 	},
 
 	set useQuaternion ( value ) {
 
-		console.warn( 'DEPRECATED: Object3D\'s .useQuaternion has been removed. The library now uses quaternions by default.' );
+		console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
 
 	},
 
@@ -210,7 +246,7 @@ THREE.Object3D.prototype = {
 
 	translate: function ( distance, axis ) {
 
-		console.warn( 'DEPRECATED: Object3D\'s .translate() has been removed. Use .translateOnAxis( axis, distance ) instead. Note args have been changed.' );
+		console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
 		return this.translateOnAxis( axis, distance );
 
 	},
@@ -357,6 +393,8 @@ THREE.Object3D.prototype = {
 		}
 
 	},
+	
+	raycast: function () {},
 
 	traverse: function ( callback ) {
 
@@ -432,27 +470,11 @@ THREE.Object3D.prototype = {
 
 	getChildByName: function ( name, recursive ) {
 
-		console.warn( 'DEPRECATED: Object3D\'s .getChildByName() has been renamed to .getObjectByName().' );
+		console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
 		return this.getObjectByName( name, recursive );
 
 	},
 
-	getDescendants: function ( array ) {
-
-		if ( array === undefined ) array = [];
-
-		Array.prototype.push.apply( array, this.children );
-
-		for ( var i = 0, l = this.children.length; i < l; i ++ ) {
-
-			this.children[ i ].getDescendants( array );
-
-		}
-
-		return array;
-
-	},
-
 	updateMatrix: function () {
 
 		this.matrix.compose( this.position, this.quaternion, this.scale );

+ 17 - 420
src/core/Raycaster.js

@@ -14,15 +14,15 @@
 		this.near = near || 0;
 		this.far = far || Infinity;
 
-	};
-
-	var sphere = new THREE.Sphere();
-	var localRay = new THREE.Ray();
-	var facePlane = new THREE.Plane();
-	var intersectPoint = new THREE.Vector3();
-	var matrixPosition = new THREE.Vector3();
+		this.params = {
+			Sprite: {},
+			Mesh: {},
+			PointCloud: { threshold: 1 },
+			LOD: {},
+			Line: {}
+		};
 
-	var inverseMatrix = new THREE.Matrix4();
+	};
 
 	var descSort = function ( a, b ) {
 
@@ -30,397 +30,17 @@
 
 	};
 
-	var vA = new THREE.Vector3();
-	var vB = new THREE.Vector3();
-	var vC = new THREE.Vector3();
-
-	var intersectObject = function ( object, raycaster, intersects ) {
-
-		if ( object instanceof THREE.Sprite ) {
-
-			matrixPosition.setFromMatrixPosition( object.matrixWorld );
-			
-			var distance = raycaster.ray.distanceToPoint( matrixPosition );
-
-			if ( distance > object.scale.x ) {
-
-				return intersects;
-
-			}
-
-			intersects.push( {
-
-				distance: distance,
-				point: object.position,
-				face: null,
-				object: object
-
-			} );
-
-
-		} else if ( object instanceof THREE.PointCloud ) {
-
-			var vertices = object.geometry.vertices;
-
-			for ( var i = 0; i < vertices.length; i ++ ) {
-
-				var v = vertices[ i ];
-
-				matrixPosition.copy( v ).applyMatrix4( object.matrixWorld );
-
-				var distance = raycaster.ray.distanceToPoint( matrixPosition );
-
-				if ( distance < 1 ) { // needs a better test; particle size?
-
-					intersects.push( {
-
-						distance: distance,
-						index: i,
-						face: null,
-						object: object
-
-					} );
-
-				}
-
-			}
-
-		} else if ( object instanceof THREE.LOD ) {
-
-			matrixPosition.setFromMatrixPosition( object.matrixWorld );
-			var distance = raycaster.ray.origin.distanceTo( matrixPosition );
-
-			intersectObject( object.getObjectForDistance( distance ), raycaster, intersects );
-
-		} else if ( object instanceof THREE.Mesh ) {
-
-			var geometry = object.geometry;
-
-			// Checking boundingSphere distance to ray
-
-			if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
-
-			sphere.copy( geometry.boundingSphere );
-			sphere.applyMatrix4( object.matrixWorld );
-
-			if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
-
-				return intersects;
-
-			}
-
-			// Check boundingBox before continuing
-			
-			inverseMatrix.getInverse( object.matrixWorld );  
-			localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
-
-			if ( geometry.boundingBox !== null ) {
-
-				if ( localRay.isIntersectionBox( geometry.boundingBox ) === false )  {
-
-					return intersects;
-
-				}
-
-			} 
-
-			if ( geometry instanceof THREE.BufferGeometry ) {
-
-				var material = object.material;
-
-				if ( material === undefined ) return intersects;
-
-				var attributes = geometry.attributes;
-
-				var a, b, c;
-				var precision = raycaster.precision;
-
-				if ( attributes.index !== undefined ) {
-
-					var indices = attributes.index.array;
-					var positions = attributes.position.array;
-					var offsets = geometry.offsets;
-
-					if ( offsets.length === 0 ) {
-
-						offsets = [ { start: 0, count: indices.length, index: 0 } ];
-
-					}
-
-					for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) {
-
-						var start = offsets[ oi ].start;
-						var count = offsets[ oi ].count;
-						var index = offsets[ oi ].index;
-
-						for ( var i = start, il = start + count; i < il; i += 3 ) {
-
-							a = index + indices[ i ];
-							b = index + indices[ i + 1 ]; 
-							c = index + indices[ i + 2 ];
-
-							vA.set(
-								positions[ a * 3 ],
-								positions[ a * 3 + 1 ],
-								positions[ a * 3 + 2 ]
-							);
-							vB.set(
-								positions[ b * 3 ],
-								positions[ b * 3 + 1 ],
-								positions[ b * 3 + 2 ]
-							);
-							vC.set(
-								positions[ c * 3 ],
-								positions[ c * 3 + 1 ],
-								positions[ c * 3 + 2 ]
-							);
-
-							
-							if ( material.side === THREE.BackSide ) {
-							
-								var intersectionPoint = localRay.intersectTriangle( vC, vB, vA, true ); 
-
-							} else {
-
-								var intersectionPoint = localRay.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );
-
-							}
-
-							if ( intersectionPoint === null ) continue;
-
-							intersectionPoint.applyMatrix4( object.matrixWorld );
-
-							var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
-
-							if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue;
-
-							intersects.push( {
-
-								distance: distance,
-								point: intersectionPoint,
-								indices: [a, b, c],
-								face: null,
-								faceIndex: null,
-								object: object
-
-							} );
-
-						}
-
-					}
-
-				} else {
-
-					var offsets = geometry.offsets;
-					var positions = attributes.position.array;
-
-					for ( var i = 0, il = attributes.position.array.length; i < il; i += 3 ) {
-
-						a = i;
-						b = i + 1;
-						c = i + 2;
-
-						vA.set(
-							positions[ a * 3 ],
-							positions[ a * 3 + 1 ],
-							positions[ a * 3 + 2 ]
-						);
-						vB.set(
-							positions[ b * 3 ],
-							positions[ b * 3 + 1 ],
-							positions[ b * 3 + 2 ]
-						);
-						vC.set(
-							positions[ c * 3 ],
-							positions[ c * 3 + 1 ],
-							positions[ c * 3 + 2 ]
-						);
-
-						
-						if ( material.side === THREE.BackSide ) {
-							
-							var intersectionPoint = localRay.intersectTriangle( vC, vB, vA, true ); 
-
-						} else {
-
-							var intersectionPoint = localRay.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );
+	var intersectObject = function ( object, raycaster, intersects, recursive ) {
 
-						}
+		object.raycast( raycaster, intersects );
 
-						if ( intersectionPoint === null ) continue;
-
-						intersectionPoint.applyMatrix4( object.matrixWorld );
-
-						var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
-
-						if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue;
-
-						intersects.push( {
-
-							distance: distance,
-							point: intersectionPoint,
-							indices: [a, b, c],
-							face: null,
-							faceIndex: null,
-							object: object
-
-						} );
-
-					}
-
-				}
-
-			} else if ( geometry instanceof THREE.Geometry ) {
-
-				var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
-				var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
-
-				var a, b, c, d;
-				var precision = raycaster.precision;
-
-				var vertices = geometry.vertices;
-
-				for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
-
-					var face = geometry.faces[ f ];
-
-					var material = isFaceMaterial === true ? objectMaterials[ face.materialIndex ] : object.material;
-
-					if ( material === undefined ) continue;
-
-					a = vertices[ face.a ];
-					b = vertices[ face.b ];
-					c = vertices[ face.c ];
-
-					if ( material.morphTargets === true ) {
-
-						var morphTargets = geometry.morphTargets;
-						var morphInfluences = object.morphTargetInfluences;
-
-						vA.set( 0, 0, 0 );
-						vB.set( 0, 0, 0 );
-						vC.set( 0, 0, 0 );
-
-						for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
-
-							var influence = morphInfluences[ t ];
-
-							if ( influence === 0 ) continue;
-
-							var targets = morphTargets[ t ].vertices;
-
-							vA.x += ( targets[ face.a ].x - a.x ) * influence;
-							vA.y += ( targets[ face.a ].y - a.y ) * influence;
-							vA.z += ( targets[ face.a ].z - a.z ) * influence;
-
-							vB.x += ( targets[ face.b ].x - b.x ) * influence;
-							vB.y += ( targets[ face.b ].y - b.y ) * influence;
-							vB.z += ( targets[ face.b ].z - b.z ) * influence;
-
-							vC.x += ( targets[ face.c ].x - c.x ) * influence;
-							vC.y += ( targets[ face.c ].y - c.y ) * influence;
-							vC.z += ( targets[ face.c ].z - c.z ) * influence;
-
-						}
-
-						vA.add( a );
-						vB.add( b );
-						vC.add( c );
-
-						a = vA;
-						b = vB;
-						c = vC;
-
-					}
-
-					if ( material.side === THREE.BackSide ) {
-							
-						var intersectionPoint = localRay.intersectTriangle( c, b, a, true );
-
-					} else {
-								
-						var intersectionPoint = localRay.intersectTriangle( a, b, c, material.side !== THREE.DoubleSide );
-
-					}
-
-					if ( intersectionPoint === null ) continue;
-
-					intersectionPoint.applyMatrix4( object.matrixWorld );
-
-					var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
-
-					if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue;
-
-					intersects.push( {
-
-						distance: distance,
-						point: intersectionPoint,
-						face: face,
-						faceIndex: f,
-						object: object
-
-					} );
-
-				}
-
-			}
-
-		} else if ( object instanceof THREE.Line ) {
-
-			var precision = raycaster.linePrecision;
-			var precisionSq = precision * precision;
-
-			var geometry = object.geometry;
-
-			if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
-
-			// Checking boundingSphere distance to ray
-
-			sphere.copy( geometry.boundingSphere );
-			sphere.applyMatrix4( object.matrixWorld );
-			
-			if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
-
-				return intersects;
-
-			}
-			
-			inverseMatrix.getInverse( object.matrixWorld );
-			localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
-
-			/* if ( geometry instanceof THREE.BufferGeometry ) {
-
-			} else */ if ( geometry instanceof THREE.Geometry ) {
-
-				var vertices = geometry.vertices;
-				var nbVertices = vertices.length;
-				var interSegment = new THREE.Vector3();
-				var interRay = new THREE.Vector3();
-				var step = object.type === THREE.LineStrip ? 1 : 2;
-
-				for ( var i = 0; i < nbVertices - 1; i = i + step ) {
-
-					var distSq = localRay.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
-
-					if ( distSq > precisionSq ) continue;
-
-					var distance = localRay.origin.distanceTo( interRay );
-
-					if ( distance < raycaster.near || distance > raycaster.far ) continue;
-
-					intersects.push( {
+		if ( recursive === true ) {
 
-						distance: distance,
-						// What do we want? intersection point on the ray or on the segment??
-						// point: raycaster.ray.at( distance ),
-						point: interSegment.clone().applyMatrix4( object.matrixWorld ),
-						face: null,
-						faceIndex: null,
-						object: object
+			var children = object.children;
 
-					} );
+			for ( var i = 0, l = children.length; i < l; i ++ ) {
 
-				}
+				intersectObject( children[ i ], raycaster, intersects, true );
 
 			}
 
@@ -428,17 +48,6 @@
 
 	};
 
-	var intersectDescendants = function ( object, raycaster, intersects ) {
-
-		var descendants = object.getDescendants();
-
-		for ( var i = 0, l = descendants.length; i < l; i ++ ) {
-
-			intersectObject( descendants[ i ], raycaster, intersects );
-
-		}
-	};
-
 	//
 
 	THREE.Raycaster.prototype.precision = 0.0001;
@@ -454,14 +63,8 @@
 	THREE.Raycaster.prototype.intersectObject = function ( object, recursive ) {
 
 		var intersects = [];
-
-		if ( recursive === true ) {
-
-			intersectDescendants( object, this, intersects );
-
-		}
-
-		intersectObject( object, this, intersects );
+		
+		intersectObject( object, this, intersects, recursive );
 
 		intersects.sort( descSort );
 
@@ -475,13 +78,7 @@
 
 		for ( var i = 0, l = objects.length; i < l; i ++ ) {
 
-			intersectObject( objects[ i ], this, intersects );
-
-			if ( recursive === true ) {
-
-				intersectDescendants( objects[ i ], this, intersects );
-
-			}
+			intersectObject( objects[ i ], this, intersects, recursive );
 
 		}
 

+ 1 - 1
src/extras/GeometryUtils.js

@@ -9,7 +9,7 @@ THREE.GeometryUtils = {
 
 	merge: function ( geometry1, geometry2, materialIndexOffset ) {
 
-		console.warn( 'DEPRECATED: GeometryUtils\'s .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
+		console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
 
 		var matrix;
 

+ 1 - 456
src/extras/ImageUtils.js

@@ -1,6 +1,7 @@
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author mrdoob / http://mrdoob.com/
+ * @author Daosheng Mu / https://github.com/DaoshengMu/
  */
 
 THREE.ImageUtils = {
@@ -33,46 +34,6 @@ THREE.ImageUtils = {
 
 	},
 
-	loadCompressedTexture: function ( url, mapping, onLoad, onError ) {
-
-		var texture = new THREE.CompressedTexture();
-		texture.mapping = mapping;
-
-		var request = new XMLHttpRequest();
-
-		request.onload = function () {
-
-			var buffer = request.response;
-			var dds = THREE.ImageUtils.parseDDS( buffer, true );
-
-			texture.format = dds.format;
-
-			texture.mipmaps = dds.mipmaps;
-			texture.image.width = dds.width;
-			texture.image.height = dds.height;
-
-			// gl.generateMipmap fails for compressed textures
-			// mipmaps must be embedded in the DDS file
-			// or texture filters must not use mipmapping
-
-			texture.generateMipmaps = false;
-
-			texture.needsUpdate = true;
-
-			if ( onLoad ) onLoad( texture );
-
-		}
-
-		request.onerror = onError;
-
-		request.open( 'GET', url, true );
-		request.responseType = "arraybuffer";
-		request.send( null );
-
-		return texture;
-
-	},
-
 	loadTextureCube: function ( array, mapping, onLoad, onError ) {
 
 		var images = [];
@@ -112,422 +73,6 @@ THREE.ImageUtils = {
 
 	},
 
-	loadCompressedTextureCube: function ( array, mapping, onLoad, onError ) {
-
-		var images = [];
-		images.loadCount = 0;
-
-		var texture = new THREE.CompressedTexture();
-		texture.image = images;
-		if ( mapping !== undefined ) texture.mapping = mapping;
-
-		// no flipping for cube textures
-		// (also flipping doesn't work for compressed textures )
-
-		texture.flipY = false;
-
-		// can't generate mipmaps for compressed textures
-		// mips must be embedded in DDS files
-
-		texture.generateMipmaps = false;
-
-		var generateCubeFaceCallback = function ( rq, img ) {
-
-			return function () {
-
-				var buffer = rq.response;
-				var dds = THREE.ImageUtils.parseDDS( buffer, true );
-
-				img.format = dds.format;
-
-				img.mipmaps = dds.mipmaps;
-				img.width = dds.width;
-				img.height = dds.height;
-
-				images.loadCount += 1;
-
-				if ( images.loadCount === 6 ) {
-
-					texture.format = dds.format;
-					texture.needsUpdate = true;
-					if ( onLoad ) onLoad( texture );
-
-				}
-
-			}
-
-		}
-
-		// compressed cubemap textures as 6 separate DDS files
-
-		if ( array instanceof Array ) {
-
-			for ( var i = 0, il = array.length; i < il; ++ i ) {
-
-				var cubeImage = {};
-				images[ i ] = cubeImage;
-
-				var request = new XMLHttpRequest();
-
-				request.onload = generateCubeFaceCallback( request, cubeImage );
-				request.onerror = onError;
-
-				var url = array[ i ];
-
-				request.open( 'GET', url, true );
-				request.responseType = "arraybuffer";
-				request.send( null );
-
-			}
-
-		// compressed cubemap texture stored in a single DDS file
-
-		} else {
-
-			var url = array;
-			var request = new XMLHttpRequest();
-
-			request.onload = function( ) {
-
-				var buffer = request.response;
-				var dds = THREE.ImageUtils.parseDDS( buffer, true );
-
-				if ( dds.isCubemap ) {
-
-					var faces = dds.mipmaps.length / dds.mipmapCount;
-
-					for ( var f = 0; f < faces; f ++ ) {
-
-						images[ f ] = { mipmaps : [] };
-
-						for ( var i = 0; i < dds.mipmapCount; i ++ ) {
-
-							images[ f ].mipmaps.push( dds.mipmaps[ f * dds.mipmapCount + i ] );
-							images[ f ].format = dds.format;
-							images[ f ].width = dds.width;
-							images[ f ].height = dds.height;
-
-						}
-
-					}
-
-					texture.format = dds.format;
-					texture.needsUpdate = true;
-					if ( onLoad ) onLoad( texture );
-
-				}
-
-			}
-
-			request.onerror = onError;
-
-			request.open( 'GET', url, true );
-			request.responseType = "arraybuffer";
-			request.send( null );
-
-		}
-
-		return texture;
-
-	},
-
-	loadDDSTexture: function ( url, mapping, onLoad, onError ) {
-
-		var images = [];
-		images.loadCount = 0;
-
-		var texture = new THREE.CompressedTexture();
-		texture.image = images;
-		if ( mapping !== undefined ) texture.mapping = mapping;
-
-		// no flipping for cube textures
-		// (also flipping doesn't work for compressed textures )
-
-		texture.flipY = false;
-
-		// can't generate mipmaps for compressed textures
-		// mips must be embedded in DDS files
-
-		texture.generateMipmaps = false;
-
-		{
-			var request = new XMLHttpRequest();
-
-			request.onload = function( ) {
-
-				var buffer = request.response;
-				var dds = THREE.ImageUtils.parseDDS( buffer, true );
-
-				if ( dds.isCubemap ) {
-
-					var faces = dds.mipmaps.length / dds.mipmapCount;
-
-					for ( var f = 0; f < faces; f ++ ) {
-
-						images[ f ] = { mipmaps : [] };
-
-						for ( var i = 0; i < dds.mipmapCount; i ++ ) {
-
-							images[ f ].mipmaps.push( dds.mipmaps[ f * dds.mipmapCount + i ] );
-							images[ f ].format = dds.format;
-							images[ f ].width = dds.width;
-							images[ f ].height = dds.height;
-
-						}
-
-					}
-
-
-				} else {
-					texture.image.width = dds.width;
-					texture.image.height = dds.height;
-					texture.mipmaps = dds.mipmaps;
-				}
-
-				texture.format = dds.format;
-				texture.needsUpdate = true;
-				if ( onLoad ) onLoad( texture );
-
-			}
-
-			request.onerror = onError;
-
-			request.open( 'GET', url, true );
-			request.responseType = "arraybuffer";
-			request.send( null );
-
-		}
-
-		return texture;
-
-	},
-
-	parseDDS: function ( buffer, loadMipmaps ) {
-
-		var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
-
-		// Adapted from @toji's DDS utils
-		//	https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
-
-		// All values and structures referenced from:
-		// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
-
-		var DDS_MAGIC = 0x20534444;
-
-		var DDSD_CAPS = 0x1,
-			DDSD_HEIGHT = 0x2,
-			DDSD_WIDTH = 0x4,
-			DDSD_PITCH = 0x8,
-			DDSD_PIXELFORMAT = 0x1000,
-			DDSD_MIPMAPCOUNT = 0x20000,
-			DDSD_LINEARSIZE = 0x80000,
-			DDSD_DEPTH = 0x800000;
-
-		var DDSCAPS_COMPLEX = 0x8,
-			DDSCAPS_MIPMAP = 0x400000,
-			DDSCAPS_TEXTURE = 0x1000;
-
-		var DDSCAPS2_CUBEMAP = 0x200,
-			DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
-			DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
-			DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
-			DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
-			DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
-			DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
-			DDSCAPS2_VOLUME = 0x200000;
-
-		var DDPF_ALPHAPIXELS = 0x1,
-			DDPF_ALPHA = 0x2,
-			DDPF_FOURCC = 0x4,
-			DDPF_RGB = 0x40,
-			DDPF_YUV = 0x200,
-			DDPF_LUMINANCE = 0x20000;
-
-		function fourCCToInt32( value ) {
-
-			return value.charCodeAt(0) +
-				(value.charCodeAt(1) << 8) +
-				(value.charCodeAt(2) << 16) +
-				(value.charCodeAt(3) << 24);
-
-		}
-
-		function int32ToFourCC( value ) {
-
-			return String.fromCharCode(
-				value & 0xff,
-				(value >> 8) & 0xff,
-				(value >> 16) & 0xff,
-				(value >> 24) & 0xff
-			);
-		}
-
-		function loadARGBMip( buffer, dataOffset, width, height ) {
-			var dataLength = width*height*4;
-			var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength );
-			var byteArray = new Uint8Array( dataLength );
-			var dst = 0;
-			var src = 0;
-			for ( var y = 0; y < height; y++ ) {
-				for ( var x = 0; x < width; x++ ) {
-					var b = srcBuffer[src]; src++;
-					var g = srcBuffer[src]; src++;
-					var r = srcBuffer[src]; src++;
-					var a = srcBuffer[src]; src++;
-					byteArray[dst] = r; dst++;	//r
-					byteArray[dst] = g; dst++;	//g
-					byteArray[dst] = b; dst++;	//b
-					byteArray[dst] = a; dst++;	//a
-				}
-			}
-			return byteArray;
-		}
-
-		var FOURCC_DXT1 = fourCCToInt32("DXT1");
-		var FOURCC_DXT3 = fourCCToInt32("DXT3");
-		var FOURCC_DXT5 = fourCCToInt32("DXT5");
-
-		var headerLengthInt = 31; // The header length in 32 bit ints
-
-		// Offsets into the header array
-
-		var off_magic = 0;
-
-		var off_size = 1;
-		var off_flags = 2;
-		var off_height = 3;
-		var off_width = 4;
-
-		var off_mipmapCount = 7;
-
-		var off_pfFlags = 20;
-		var off_pfFourCC = 21;
-		var off_RGBBitCount = 22;
-		var off_RBitMask = 23;
-		var off_GBitMask = 24;
-		var off_BBitMask = 25;
-		var off_ABitMask = 26;
-
-		var off_caps = 27;
-		var off_caps2 = 28;
-		var off_caps3 = 29;
-		var off_caps4 = 30;
-
-		// Parse header
-
-		var header = new Int32Array( buffer, 0, headerLengthInt );
-
-		if ( header[ off_magic ] !== DDS_MAGIC ) {
-
-			console.error( "ImageUtils.parseDDS(): Invalid magic number in DDS header" );
-			return dds;
-
-		}
-
-		if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) {
-
-			console.error( "ImageUtils.parseDDS(): Unsupported format, must contain a FourCC code" );
-			return dds;
-
-		}
-
-		var blockBytes;
-
-		var fourCC = header[ off_pfFourCC ];
-
-		var isRGBAUncompressed = false;
-
-		switch ( fourCC ) {
-
-			case FOURCC_DXT1:
-
-				blockBytes = 8;
-				dds.format = THREE.RGB_S3TC_DXT1_Format;
-				break;
-
-			case FOURCC_DXT3:
-
-				blockBytes = 16;
-				dds.format = THREE.RGBA_S3TC_DXT3_Format;
-				break;
-
-			case FOURCC_DXT5:
-
-				blockBytes = 16;
-				dds.format = THREE.RGBA_S3TC_DXT5_Format;
-				break;
-
-			default:
-
-				if( header[off_RGBBitCount] ==32 
-					&& header[off_RBitMask]&0xff0000
-					&& header[off_GBitMask]&0xff00 
-					&& header[off_BBitMask]&0xff
-					&& header[off_ABitMask]&0xff000000  ) {
-					isRGBAUncompressed = true;
-					blockBytes = 64;
-					dds.format = THREE.RGBAFormat;
-				} else {
-					console.error( "ImageUtils.parseDDS(): Unsupported FourCC code: ", int32ToFourCC( fourCC ) );
-					return dds;
-				}
-		}
-
-		dds.mipmapCount = 1;
-
-		if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
-
-			dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
-
-		}
-
-		//TODO: Verify that all faces of the cubemap are present with DDSCAPS2_CUBEMAP_POSITIVEX, etc.
-
-		dds.isCubemap = header[ off_caps2 ] & DDSCAPS2_CUBEMAP ? true : false;
-
-		dds.width = header[ off_width ];
-		dds.height = header[ off_height ];
-
-		var dataOffset = header[ off_size ] + 4;
-
-		// Extract mipmaps buffers
-
-		var width = dds.width;
-		var height = dds.height;
-
-		var faces = dds.isCubemap ? 6 : 1;
-
-		for ( var face = 0; face < faces; face ++ ) {
-
-			for ( var i = 0; i < dds.mipmapCount; i ++ ) {
-
-				if( isRGBAUncompressed ) {
-					var byteArray = loadARGBMip( buffer, dataOffset, width, height );
-					var dataLength = byteArray.length;
-				} else {
-					var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;
-					var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
-				}
-				
-				var mipmap = { "data": byteArray, "width": width, "height": height };
-				dds.mipmaps.push( mipmap );
-
-				dataOffset += dataLength;
-
-				width = Math.max( width * 0.5, 1 );
-				height = Math.max( height * 0.5, 1 );
-
-			}
-
-			width = dds.width;
-			height = dds.height;
-
-		}
-
-		return dds;
-
-	},
-
 	getNormalMap: function ( image, depth ) {
 
 		// Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/

+ 9 - 4
src/extras/geometries/CubeGeometry.js

@@ -1,6 +1,11 @@
-// DEPRECATED
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
 
 THREE.CubeGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) {
-	console.warn( 'DEPRECATED: THREE.CubeGeometry is deprecated. Use THREE.BoxGeometry instead.' );
- 	return new THREE.BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments );
- };
+
+	console.warn( 'THEE.CubeGeometry has been renamed to THREE.BoxGeometry.' );
+	return new THREE.BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments );
+
+ };

+ 27 - 24
src/extras/helpers/ArrowHelper.js

@@ -14,42 +14,45 @@
  *  headWidth - Number
  */
 
-THREE.ArrowHelper = function ( dir, origin, length, color, headLength, headWidth ) {
+THREE.ArrowHelper = ( function () {
 
-	// dir is assumed to be normalized
+	var lineGeometry = new THREE.Geometry();
+	lineGeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
+
+	var coneGeometry = new THREE.CylinderGeometry( 0, 0.5, 1, 5, 1 );
+	coneGeometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, - 0.5, 0 ) );
 
-	THREE.Object3D.call( this );
+	return function ( dir, origin, length, color, headLength, headWidth ) {
 
-	if ( color === undefined ) color = 0xffff00;
-	if ( length === undefined ) length = 1;
-	if ( headLength === undefined ) headLength = 0.2 * length;
-	if ( headWidth === undefined ) headWidth = 0.2 * headLength;
+		// dir is assumed to be normalized
 
-	this.position = origin;
+		THREE.Object3D.call( this );
 
-	var lineGeometry = new THREE.Geometry();
-	lineGeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
-	lineGeometry.vertices.push( new THREE.Vector3( 0, 1, 0 ) );
+		if ( color === undefined ) color = 0xffff00;
+		if ( length === undefined ) length = 1;
+		if ( headLength === undefined ) headLength = 0.2 * length;
+		if ( headWidth === undefined ) headWidth = 0.2 * headLength;
 
-	this.line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: color } ) );
-	this.line.matrixAutoUpdate = false;
-	this.add( this.line );
+		this.position.copy( origin );
 
-	var coneGeometry = new THREE.CylinderGeometry( 0, 0.5, 1, 5, 1 );
-	coneGeometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, - 0.5, 0 ) );
+		this.line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: color } ) );
+		this.line.matrixAutoUpdate = false;
+		this.add( this.line );
 
-	this.cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color: color } ) );
-	this.cone.matrixAutoUpdate = false;
-	this.add( this.cone );
+		this.cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color: color } ) );
+		this.cone.matrixAutoUpdate = false;
+		this.add( this.cone );
 
-	this.setDirection( dir );
-	this.setLength( length, headLength, headWidth );
+		this.setDirection( dir );
+		this.setLength( length, headLength, headWidth );
 
-};
+	}
+
+}() );
 
 THREE.ArrowHelper.prototype = Object.create( THREE.Object3D.prototype );
 
-THREE.ArrowHelper.prototype.setDirection = function () {
+THREE.ArrowHelper.prototype.setDirection = ( function () {
 
 	var axis = new THREE.Vector3();
 	var radians;
@@ -78,7 +81,7 @@ THREE.ArrowHelper.prototype.setDirection = function () {
 
 	};
 
-}();
+}() );
 
 THREE.ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {
 

+ 1 - 2
src/extras/helpers/VertexNormalsHelper.js

@@ -25,8 +25,7 @@ THREE.VertexNormalsHelper = function ( object, size, hex, linewidth ) {
 
 		for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
 
-			geometry.vertices.push( new THREE.Vector3() );
-			geometry.vertices.push( new THREE.Vector3() );
+			geometry.vertices.push( new THREE.Vector3(), new THREE.Vector3() );
 
 		}
 

+ 11 - 11
src/extras/helpers/WireframeHelper.js

@@ -46,9 +46,7 @@ THREE.WireframeHelper = function ( object, hex ) {
 
 		}
 
-		geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2 * 3, 3 ) );
-
-		var coords = geometry.attributes.position.array;
+		var coords = new Float32Array( numEdges * 2 * 3 );
 
 		for ( var i = 0, l = numEdges; i < l; i ++ ) {
 
@@ -65,7 +63,9 @@ THREE.WireframeHelper = function ( object, hex ) {
 
 		}
 
-	} else if ( object.geometry instanceof THREE.BufferGeometry && object.geometry.attributes.index !== undefined ) { // indexed BufferGeometry
+		geometry.addAttribute( 'position', new THREE.BufferAttribute( coords, 3 ) );
+
+	} else if ( object.geometry instanceof THREE.BufferGeometry && object.geometry.attributes.index !== undefined ) { // Indexed BufferGeometry
 
 		var vertices = object.geometry.attributes.position.array;
 		var indices = object.geometry.attributes.index.array;
@@ -106,9 +106,7 @@ THREE.WireframeHelper = function ( object, hex ) {
 
 		}
 
-		geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2 * 3, 3 ) );
-
-		var coords = geometry.attributes.position.array;
+		var coords = new Float32Array( numEdges * 2 * 3 );
 
 		for ( var i = 0, l = numEdges; i < l; i ++ ) {
 
@@ -124,15 +122,15 @@ THREE.WireframeHelper = function ( object, hex ) {
 
 		}
 
-	} else if ( object.geometry instanceof THREE.BufferGeometry	) { // non-indexed BufferGeometry
+		geometry.addAttribute( 'position', new THREE.BufferAttribute( coords, 3 ) );
+
+	} else if ( object.geometry instanceof THREE.BufferGeometry ) { // non-indexed BufferGeometry
 
 		var vertices = object.geometry.attributes.position.array;
 		var numEdges = vertices.length / 3;
 		var numTris = numEdges / 3;
 
-		geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2 * 3, 3 ) );
-
-		var coords = geometry.attributes.position.array;
+		var coords = new Float32Array( numEdges * 2 * 3 );
 
 		for ( var i = 0, l = numTris; i < l; i ++ ) {
 
@@ -154,6 +152,8 @@ THREE.WireframeHelper = function ( object, hex ) {
 
 		}
 
+		geometry.addAttribute( 'position', new THREE.BufferAttribute( coords, 3 ) );
+
 	}
 
 	THREE.Line.call( this, geometry, new THREE.LineBasicMaterial( { color: color } ), THREE.LinePieces );

+ 2 - 0
src/extras/renderers/plugins/LensFlarePlugin.js

@@ -158,6 +158,8 @@ THREE.LensFlarePlugin = function () {
 
 			flare = flares[ i ];
 
+			if ( flare.visible === false ) continue;
+			
 			tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
 
 			tempPosition.applyMatrix4( camera.matrixWorldInverse );

+ 70 - 44
src/loaders/Loader.js

@@ -114,38 +114,60 @@ THREE.Loader.prototype = {
 
 		function create_texture( where, name, sourceFile, repeat, offset, wrap, anisotropy ) {
 
-			var isCompressed = /\.dds$/i.test( sourceFile );
-
 			var fullPath = texturePath + sourceFile;
 
-			if ( isCompressed ) {
+			var texture;
+
+			var loader = THREE.Loader.Handlers.get( fullPath );
 
-				var texture = THREE.ImageUtils.loadCompressedTexture( fullPath );
+			if ( loader !== null ) {
 
-				where[ name ] = texture;
+				texture = loader.load( fullPath );
 
 			} else {
 
-				var texture = document.createElement( 'canvas' );
+				texture = new THREE.Texture( document.createElement( 'canvas' ) );
+
+				loader = scope.imageLoader;
+				loader.crossOrigin = scope.crossOrigin;
+				loader.load( fullPath, function ( image ) {
 
-				where[ name ] = new THREE.Texture( texture );
+					if ( THREE.Math.isPowerOfTwo( image.width ) === false ||
+						 THREE.Math.isPowerOfTwo( image.height ) === false ) {
+
+						var width = nearest_pow2( image.width );
+						var height = nearest_pow2( image.height );
+
+						texture.image.width = width;
+						texture.image.height = height;
+						texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height );
+
+					} else {
+
+						texture.image = image;
+
+					}
+
+					texture.needsUpdate = true;
+
+				} );
 
 			}
 
-			where[ name ].sourceFile = sourceFile;
+			texture.sourceFile = sourceFile;
 
-			if( repeat ) {
+			if ( repeat ) {
 
-				where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
+				texture.repeat.set( repeat[ 0 ], repeat[ 1 ] );
 
-				if ( repeat[ 0 ] !== 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
-				if ( repeat[ 1 ] !== 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
+				if ( repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
+				if ( repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
 
 			}
 
 			if ( offset ) {
 
-				where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
+				texture.offset.set( offset[ 0 ], offset[ 1 ] );
 
 			}
 
@@ -156,45 +178,18 @@ THREE.Loader.prototype = {
 					"mirror": THREE.MirroredRepeatWrapping
 				}
 
-				if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
-				if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
+				if ( wrapMap[ wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ wrap[ 0 ] ];
+				if ( wrapMap[ wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ wrap[ 1 ] ];
 
 			}
 
 			if ( anisotropy ) {
 
-				where[ name ].anisotropy = anisotropy;
+				texture.anisotropy = anisotropy;
 
 			}
 
-			if ( ! isCompressed ) {
-
-				var texture = where[ name ];
-
-				scope.imageLoader.crossOrigin = scope.crossOrigin;
-				scope.imageLoader.load( fullPath, function ( image ) {
-
-					if ( THREE.Math.isPowerOfTwo( image.width ) === false ||
-						 THREE.Math.isPowerOfTwo( image.height ) === false ) {
-
-						var width = nearest_pow2( image.width );
-						var height = nearest_pow2( image.height );
-
-						texture.image.width = width;
-						texture.image.height = height;
-						texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height );
-
-					} else {
-
-						texture.image = image;
-
-					}
-
-					texture.needsUpdate = true;
-
-				} );
-
-			}
+			where[ name ] = texture;
 
 		}
 
@@ -438,3 +433,34 @@ THREE.Loader.prototype = {
 	}
 
 };
+
+THREE.Loader.Handlers = {
+
+	handlers: [],
+
+	add: function ( regex, loader ) {
+
+		this.handlers.push( regex, loader );
+
+	},
+
+	get: function ( file ) {
+
+		for ( var i = 0, l = this.handlers.length; i < l; i += 2 ) {
+
+			var regex = this.handlers[ i ];
+			var loader  = this.handlers[ i + 1 ];
+
+			if ( regex.test( file ) ) {
+
+				return loader;
+
+			}
+
+		}
+
+		return null;
+
+	}
+
+};

+ 1 - 1
src/loaders/ObjectLoader.js

@@ -70,7 +70,7 @@ THREE.ObjectLoader.prototype = {
 						break;
 
 					case 'BoxGeometry':
-					case 'CubeGeometry': // DEPRECATED
+					case 'CubeGeometry': // backwards compatible
 
 						geometry = new THREE.BoxGeometry(
 							data.width,

+ 10 - 3
src/loaders/XHRLoader.js

@@ -27,14 +27,15 @@ THREE.XHRLoader.prototype = {
 		}
 
 		var request = new XMLHttpRequest();
+		request.open( 'GET', url, true );
 
 		if ( onLoad !== undefined ) {
 
 			request.addEventListener( 'load', function ( event ) {
 
-				scope.cache.add( url, event.target.responseText );
+				scope.cache.add( url, this.response );
 
-				onLoad( event.target.responseText );
+				onLoad( this.response );
 				scope.manager.itemEnd( url );
 
 			}, false );
@@ -62,14 +63,20 @@ THREE.XHRLoader.prototype = {
 		}
 
 		if ( this.crossOrigin !== undefined ) request.crossOrigin = this.crossOrigin;
+		if ( this.responseType !== undefined ) request.responseType = this.responseType;
 
-		request.open( 'GET', url, true );
 		request.send( null );
 
 		scope.manager.itemStart( url );
 
 	},
 
+	setResponseType: function ( value ) {
+
+		this.responseType = value;
+
+	},
+
 	setCrossOrigin: function ( value ) {
 
 		this.crossOrigin = value;

+ 2 - 2
src/materials/PointCloudMaterial.js

@@ -65,7 +65,7 @@ THREE.PointCloudMaterial.prototype.clone = function () {
 
 THREE.ParticleSystemMaterial = function ( parameters ) {
 
-	console.warn( 'THREE.ParticleSystemMaterial has been DEPRECATED. Use THREE.PointCloudMaterial instead.' );
+	console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointCloudMaterial.' );
 	return new THREE.PointCloudMaterial( parameters );
 
-}
+}

+ 2 - 2
src/math/Euler.js

@@ -212,7 +212,7 @@ THREE.Euler.prototype = {
 
 		} else {
 
-			console.warn( 'WARNING: Euler.setFromRotationMatrix() given unsupported order: ' + order )
+			console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order )
 
 		}
 
@@ -277,7 +277,7 @@ THREE.Euler.prototype = {
 
 		} else {
 
-			console.warn( 'WARNING: Euler.setFromQuaternion() given unsupported order: ' + order )
+			console.warn( 'THREE.Euler: .setFromQuaternion() given unsupported order: ' + order )
 
 		}
 

+ 2 - 2
src/math/Matrix3.js

@@ -64,14 +64,14 @@ THREE.Matrix3.prototype = {
 
 	multiplyVector3: function ( vector ) {
 
-		console.warn( 'DEPRECATED: Matrix3\'s .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
+		console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
 		return vector.applyMatrix3( this );
 
 	},
 
 	multiplyVector3Array: function ( a ) {
 
-		console.warn( 'DEPRECATED: Matrix3\'s .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
+		console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
 		return this.applyToVector3Array( a );
 
 	},

+ 15 - 15
src/math/Matrix4.js

@@ -70,7 +70,7 @@ THREE.Matrix4.prototype = {
 
 	extractPosition: function ( m ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .extractPosition() has been renamed to .copyPosition().' );
+		console.warn( 'THREEMatrix4: .extractPosition() has been renamed to .copyPosition().' );
 		return this.copyPosition( m );
 
 	},
@@ -123,7 +123,7 @@ THREE.Matrix4.prototype = {
 
 		if ( euler instanceof THREE.Euler === false ) {
 
-			console.error( 'ERROR: Matrix\'s .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.  Please update your code.' );
+			console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
 
 		}
 
@@ -249,7 +249,7 @@ THREE.Matrix4.prototype = {
 
 	setRotationFromQuaternion: function ( q ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .setRotationFromQuaternion() has been deprecated in favor of makeRotationFromQuaternion.  Please update your code.' );
+		console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );
 
 		return this.makeRotationFromQuaternion( q );
 
@@ -336,7 +336,7 @@ THREE.Matrix4.prototype = {
 
 		if ( n !== undefined ) {
 
-			console.warn( 'DEPRECATED: Matrix4\'s .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
+			console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
 			return this.multiplyMatrices( m, n );
 
 		}
@@ -415,21 +415,21 @@ THREE.Matrix4.prototype = {
 
 	multiplyVector3: function ( vector ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );
+		console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );
 		return vector.applyProjection( this );
 
 	},
 
 	multiplyVector4: function ( vector ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
+		console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
 		return vector.applyMatrix4( this );
 
 	},
 
 	multiplyVector3Array: function ( a ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
+		console.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );
 		return this.applyToVector3Array( a );
 
 	},
@@ -465,7 +465,7 @@ THREE.Matrix4.prototype = {
 
 	rotateAxis: function ( v ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
+		console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
 
 		v.transformDirection( this );
 
@@ -473,7 +473,7 @@ THREE.Matrix4.prototype = {
 
 	crossVector: function ( vector ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
+		console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
 		return vector.applyMatrix4( this );
 
 	},
@@ -579,7 +579,7 @@ THREE.Matrix4.prototype = {
 
 		return function () {
 
-			console.warn( 'DEPRECATED: Matrix4\'s .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
+			console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
 
 			var te = this.elements;
 			return v1.set( te[12], te[13], te[14] );
@@ -657,31 +657,31 @@ THREE.Matrix4.prototype = {
 
 	translate: function ( v ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .translate() has been removed.');
+		console.warn( 'THREE.Matrix4: .translate() has been removed.');
 
 	},
 
 	rotateX: function ( angle ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .rotateX() has been removed.');
+		console.warn( 'THREE.Matrix4: .rotateX() has been removed.');
 
 	},
 
 	rotateY: function ( angle ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .rotateY() has been removed.');
+		console.warn( 'THREE.Matrix4: .rotateY() has been removed.');
 
 	},
 
 	rotateZ: function ( angle ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .rotateZ() has been removed.');
+		console.warn( 'THREE.Matrix4: .rotateZ() has been removed.');
 
 	},
 
 	rotateByAxis: function ( axis, angle ) {
 
-		console.warn( 'DEPRECATED: Matrix4\'s .rotateByAxis() has been removed.');
+		console.warn( 'THREE.Matrix4: .rotateByAxis() has been removed.');
 
 	},
 

+ 9 - 3
src/math/Quaternion.js

@@ -102,7 +102,7 @@ THREE.Quaternion.prototype = {
 
 		if ( euler instanceof THREE.Euler === false ) {
 
-			throw new Error( 'ERROR: Quaternion\'s .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.  Please update your code.' );
+			throw new Error( 'THREE.Quaternion: .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
 		}
 
 		// http://www.mathworks.com/matlabcentral/fileexchange/
@@ -313,6 +313,12 @@ THREE.Quaternion.prototype = {
 
 	},
 
+	dot: function ( v ) {
+
+		return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
+
+	},
+
 	lengthSq: function () {
 
 		return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
@@ -357,7 +363,7 @@ THREE.Quaternion.prototype = {
 
 		if ( p !== undefined ) {
 
-			console.warn( 'DEPRECATED: Quaternion\'s .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
+			console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
 			return this.multiplyQuaternions( q, p );
 
 		}
@@ -386,7 +392,7 @@ THREE.Quaternion.prototype = {
 
 	multiplyVector3: function ( vector ) {
 
-		console.warn( 'DEPRECATED: Quaternion\'s .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
+		console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
 		return vector.applyQuaternion( this );
 
 	},

+ 2 - 2
src/math/Vector2.js

@@ -78,7 +78,7 @@ THREE.Vector2.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector2\'s .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
 			return this.addVectors( v, w );
 
 		}
@@ -112,7 +112,7 @@ THREE.Vector2.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector2\'s .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
 			return this.subVectors( v, w );
 
 		}

+ 11 - 11
src/math/Vector3.js

@@ -93,7 +93,7 @@ THREE.Vector3.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector3\'s .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
 			return this.addVectors( v, w );
 
 		}
@@ -130,7 +130,7 @@ THREE.Vector3.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector3\'s .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
 			return this.subVectors( v, w );
 
 		}
@@ -157,7 +157,7 @@ THREE.Vector3.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector3\'s .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
 			return this.multiplyVectors( v, w );
 
 		}
@@ -198,7 +198,7 @@ THREE.Vector3.prototype = {
 
 			if ( euler instanceof THREE.Euler === false ) {
 
-				console.error( 'ERROR: Vector3\'s .applyEuler() now expects a Euler rotation rather than a Vector3 and order.  Please update your code.' );
+				console.error( 'THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.' );
 
 			}
 
@@ -567,7 +567,7 @@ THREE.Vector3.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector3\'s .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
 			return this.crossVectors( v, w );
 
 		}
@@ -674,19 +674,19 @@ THREE.Vector3.prototype = {
 
 	setEulerFromRotationMatrix: function ( m, order ) {
 
-		console.error( "REMOVED: Vector3\'s setEulerFromRotationMatrix has been removed in favor of Euler.setFromRotationMatrix(), please update your code.");
+		console.error( "THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.");
 
 	},
 
 	setEulerFromQuaternion: function ( q, order ) {
 
-		console.error( "REMOVED: Vector3\'s setEulerFromQuaternion: has been removed in favor of Euler.setFromQuaternion(), please update your code.");
+		console.error( "THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.");
 
 	},
 
 	getPositionFromMatrix: function ( m ) {
 
-		console.warn( "DEPRECATED: Vector3\'s .getPositionFromMatrix() has been renamed to .setFromMatrixPosition(). Please update your code." );
+		console.warn( "THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition()." );
 
 		return this.setFromMatrixPosition( m );
 
@@ -694,14 +694,14 @@ THREE.Vector3.prototype = {
 
 	getScaleFromMatrix: function ( m ) {
 
-		console.warn( "DEPRECATED: Vector3\'s .getScaleFromMatrix() has been renamed to .setFromMatrixScale(). Please update your code." );
+		console.warn( "THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale()." );
 
 		return this.setFromMatrixScale( m );
 	},
 
 	getColumnFromMatrix: function ( index, matrix ) {
 
-		console.warn( "DEPRECATED: Vector3\'s .getColumnFromMatrix() has been renamed to .setFromMatrixColumn(). Please update your code." );
+		console.warn( "THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn()." );
 
 		return this.setFromMatrixColumn( index, matrix );
 
@@ -772,4 +772,4 @@ THREE.Vector3.prototype = {
 
 	}
 
-};
+};

+ 2 - 2
src/math/Vector4.js

@@ -105,7 +105,7 @@ THREE.Vector4.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector4\'s .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
 			return this.addVectors( v, w );
 
 		}
@@ -145,7 +145,7 @@ THREE.Vector4.prototype = {
 
 		if ( w !== undefined ) {
 
-			console.warn( 'DEPRECATED: Vector4\'s .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
+			console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
 			return this.subVectors( v, w );
 
 		}

+ 16 - 0
src/objects/LOD.js

@@ -52,6 +52,22 @@ THREE.LOD.prototype.getObjectForDistance = function ( distance ) {
 
 };
 
+THREE.LOD.prototype.raycast = ( function () {
+
+	var matrixPosition = new THREE.Vector3();
+
+	return function ( raycaster, intersects ) {
+
+		matrixPosition.setFromMatrixPosition( this.matrixWorld );
+
+		var distance = raycaster.ray.origin.distanceTo( matrixPosition );
+
+		this.getObjectForDistance( distance ).raycast( raycaster, intersects );
+
+	};
+
+}() );
+
 THREE.LOD.prototype.update = function () {
 
 	var v1 = new THREE.Vector3();

+ 69 - 0
src/objects/Line.js

@@ -18,6 +18,75 @@ THREE.LinePieces = 1;
 
 THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
 
+THREE.Line.prototype.raycast = ( function () {
+
+	var inverseMatrix = new THREE.Matrix4();
+	var ray = new THREE.Ray();
+	var sphere = new THREE.Sphere();
+
+	return function ( raycaster, intersects ) {
+	
+		var precision = raycaster.linePrecision;
+		var precisionSq = precision * precision;
+
+		var geometry = this.geometry;
+
+		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
+
+		// Checking boundingSphere distance to ray
+
+		sphere.copy( geometry.boundingSphere );
+		sphere.applyMatrix4( this.matrixWorld );
+	
+		if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
+
+			return;
+
+		}
+	
+		inverseMatrix.getInverse( this.matrixWorld );
+		ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
+
+		/* if ( geometry instanceof THREE.BufferGeometry ) {
+
+		} else */ if ( geometry instanceof THREE.Geometry ) {
+
+			var vertices = geometry.vertices;
+			var nbVertices = vertices.length;
+			var interSegment = new THREE.Vector3();
+			var interRay = new THREE.Vector3();
+			var step = this.type === THREE.LineStrip ? 1 : 2;
+
+			for ( var i = 0; i < nbVertices - 1; i = i + step ) {
+
+				var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
+
+				if ( distSq > precisionSq ) continue;
+
+				var distance = ray.origin.distanceTo( interRay );
+
+				if ( distance < raycaster.near || distance > raycaster.far ) continue;
+
+				intersects.push( {
+
+					distance: distance,
+					// What do we want? intersection point on the ray or on the segment??
+					// point: raycaster.ray.at( distance ),
+					point: interSegment.clone().applyMatrix4( this.matrixWorld ),
+					face: null,
+					faceIndex: null,
+					object: this
+
+				} );
+
+			}
+
+		}
+
+	};
+
+}() );
+
 THREE.Line.prototype.clone = function ( object ) {
 
 	if ( object === undefined ) object = new THREE.Line( this.geometry, this.material, this.type );

+ 287 - 0
src/objects/Mesh.js

@@ -52,6 +52,293 @@ THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) {
 
 };
 
+
+THREE.Mesh.prototype.raycast = ( function () {
+
+	var inverseMatrix = new THREE.Matrix4();
+	var ray = new THREE.Ray();
+	var sphere = new THREE.Sphere();
+
+	var vA = new THREE.Vector3();
+	var vB = new THREE.Vector3();
+	var vC = new THREE.Vector3();
+
+	return function ( raycaster, intersects ) {
+
+		var geometry = this.geometry;
+
+		// Checking boundingSphere distance to ray
+
+		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
+
+		sphere.copy( geometry.boundingSphere );
+		sphere.applyMatrix4( this.matrixWorld );
+
+		if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
+
+			return;
+
+		}
+
+		// Check boundingBox before continuing
+
+		inverseMatrix.getInverse( this.matrixWorld );
+		ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
+
+		if ( geometry.boundingBox !== null ) {
+
+			if ( ray.isIntersectionBox( geometry.boundingBox ) === false )  {
+
+				return;
+
+			}
+
+		}
+
+		if ( geometry instanceof THREE.BufferGeometry ) {
+
+			var material = this.material;
+
+			if ( material === undefined ) return;
+
+			var attributes = geometry.attributes;
+
+			var a, b, c;
+			var precision = raycaster.precision;
+
+			if ( attributes.index !== undefined ) {
+
+				var indices = attributes.index.array;
+				var positions = attributes.position.array;
+				var offsets = geometry.offsets;
+
+				if ( offsets.length === 0 ) {
+
+					offsets = [ { start: 0, count: indices.length, index: 0 } ];
+
+				}
+
+				for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) {
+
+					var start = offsets[ oi ].start;
+					var count = offsets[ oi ].count;
+					var index = offsets[ oi ].index;
+
+					for ( var i = start, il = start + count; i < il; i += 3 ) {
+
+						a = index + indices[ i ];
+						b = index + indices[ i + 1 ];
+						c = index + indices[ i + 2 ];
+
+						vA.set(
+							positions[ a * 3 ],
+							positions[ a * 3 + 1 ],
+							positions[ a * 3 + 2 ]
+						);
+						vB.set(
+							positions[ b * 3 ],
+							positions[ b * 3 + 1 ],
+							positions[ b * 3 + 2 ]
+						);
+						vC.set(
+							positions[ c * 3 ],
+							positions[ c * 3 + 1 ],
+							positions[ c * 3 + 2 ]
+						);
+
+						
+						if ( material.side === THREE.BackSide ) {
+
+							var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true );
+
+						} else {
+
+							var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );
+
+						}
+
+						if ( intersectionPoint === null ) continue;
+
+						intersectionPoint.applyMatrix4( this.matrixWorld );
+
+						var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
+
+						if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue;
+
+						intersects.push( {
+
+							distance: distance,
+							point: intersectionPoint,
+							indices: [a, b, c],
+							face: null,
+							faceIndex: null,
+							object: this
+
+						} );
+
+					}
+
+				}
+
+			} else {
+
+				var positions = attributes.position.array;
+
+				for ( var i = 0, j = 0, il = positions.length; i < il; i += 3, j += 9 ) {
+
+					a = i;
+					b = i + 1;
+					c = i + 2;
+
+					vA.set(
+						positions[ j ],
+						positions[ j + 1 ],
+						positions[ j + 2 ]
+					);
+					vB.set(
+						positions[ j + 3 ],
+						positions[ j + 4 ],
+						positions[ j + 5 ]
+					);
+					vC.set(
+						positions[ j + 6 ],
+						positions[ j + 7 ],
+						positions[ j + 8 ]
+					);
+
+					
+					if ( material.side === THREE.BackSide ) {
+
+						var intersectionPoint = ray.intersectTriangle( vC, vB, vA, true );
+
+					} else {
+
+						var intersectionPoint = ray.intersectTriangle( vA, vB, vC, material.side !== THREE.DoubleSide );
+
+					}
+
+					if ( intersectionPoint === null ) continue;
+
+					intersectionPoint.applyMatrix4( this.matrixWorld );
+
+					var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
+
+					if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue;
+
+					intersects.push( {
+
+						distance: distance,
+						point: intersectionPoint,
+						indices: [ a, b, c ],
+						face: null,
+						faceIndex: null,
+						object: this
+
+					} );
+
+				}
+
+			}
+
+		} else if ( geometry instanceof THREE.Geometry ) {
+
+			var isFaceMaterial = this.material instanceof THREE.MeshFaceMaterial;
+			var objectMaterials = isFaceMaterial === true ? this.material.materials : null;
+
+			var a, b, c, d;
+			var precision = raycaster.precision;
+
+			var vertices = geometry.vertices;
+
+			for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
+
+				var face = geometry.faces[ f ];
+
+				var material = isFaceMaterial === true ? objectMaterials[ face.materialIndex ] : this.material;
+
+				if ( material === undefined ) continue;
+
+				a = vertices[ face.a ];
+				b = vertices[ face.b ];
+				c = vertices[ face.c ];
+
+				if ( material.morphTargets === true ) {
+
+					var morphTargets = geometry.morphTargets;
+					var morphInfluences = this.morphTargetInfluences;
+
+					vA.set( 0, 0, 0 );
+					vB.set( 0, 0, 0 );
+					vC.set( 0, 0, 0 );
+
+					for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
+
+						var influence = morphInfluences[ t ];
+
+						if ( influence === 0 ) continue;
+
+						var targets = morphTargets[ t ].vertices;
+
+						vA.x += ( targets[ face.a ].x - a.x ) * influence;
+						vA.y += ( targets[ face.a ].y - a.y ) * influence;
+						vA.z += ( targets[ face.a ].z - a.z ) * influence;
+
+						vB.x += ( targets[ face.b ].x - b.x ) * influence;
+						vB.y += ( targets[ face.b ].y - b.y ) * influence;
+						vB.z += ( targets[ face.b ].z - b.z ) * influence;
+
+						vC.x += ( targets[ face.c ].x - c.x ) * influence;
+						vC.y += ( targets[ face.c ].y - c.y ) * influence;
+						vC.z += ( targets[ face.c ].z - c.z ) * influence;
+
+					}
+
+					vA.add( a );
+					vB.add( b );
+					vC.add( c );
+
+					a = vA;
+					b = vB;
+					c = vC;
+
+				}
+
+				if ( material.side === THREE.BackSide ) {
+
+					var intersectionPoint = ray.intersectTriangle( c, b, a, true );
+
+				} else {
+
+					var intersectionPoint = ray.intersectTriangle( a, b, c, material.side !== THREE.DoubleSide );
+
+				}
+
+				if ( intersectionPoint === null ) continue;
+
+				intersectionPoint.applyMatrix4( this.matrixWorld );
+
+				var distance = raycaster.ray.origin.distanceTo( intersectionPoint );
+
+				if ( distance < precision || distance < raycaster.near || distance > raycaster.far ) continue;
+
+				intersects.push( {
+
+					distance: distance,
+					point: intersectionPoint,
+					face: face,
+					faceIndex: f,
+					object: this
+
+				} );
+
+			}
+
+		}
+
+	};
+
+}() );
+
 THREE.Mesh.prototype.clone = function ( object, recursive ) {
 
 	if ( object === undefined ) object = new THREE.Mesh( this.geometry, this.material );

+ 133 - 2
src/objects/PointCloud.js

@@ -15,6 +15,137 @@ THREE.PointCloud = function ( geometry, material ) {
 
 THREE.PointCloud.prototype = Object.create( THREE.Object3D.prototype );
 
+THREE.PointCloud.prototype.raycast = ( function () {
+
+	var inverseMatrix = new THREE.Matrix4();
+	var ray = new THREE.Ray();
+
+	return function ( raycaster, intersects ) {
+
+		var object = this;
+		var geometry = object.geometry;
+		var threshold = raycaster.params.PointCloud.threshold;
+
+		inverseMatrix.getInverse( this.matrixWorld );
+		ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
+
+		if ( geometry.boundingBox !== null ) {
+	
+			if ( ray.isIntersectionBox( geometry.boundingBox ) === false ) {
+
+				return;
+
+			}
+
+		}
+	
+		var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
+		var position = new THREE.Vector3();
+
+		var testPoint = function ( point, index ) {
+
+			var rayPointDistance = ray.distanceToPoint( point );
+
+			if ( rayPointDistance < localThreshold ) {
+
+				var intersectPoint = ray.closestPointToPoint( point );
+				intersectPoint.applyMatrix4( object.matrixWorld );
+
+				var distance = raycaster.ray.origin.distanceTo( intersectPoint );
+
+				intersects.push( {
+
+					distance: distance,
+					distanceToRay: rayPointDistance,
+					point: intersectPoint.clone(),
+					index: index,
+					face: null,
+					object: object
+
+				} );
+
+			}
+
+		};
+
+		if ( geometry instanceof THREE.BufferGeometry ) {
+	
+			var attributes = geometry.attributes;
+			var positions = attributes.position.array;
+
+			if ( attributes.index !== undefined ) {
+
+				var indices = attributes.index.array;
+				var offsets = geometry.offsets;
+
+				if ( offsets.length === 0 ) {
+
+					var offset = {
+						start: 0,
+						count: indices.length,
+						index: 0
+					};
+
+					offsets = [ offset ];
+
+				}
+
+				for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) {
+
+					var start = offsets[ oi ].start;
+					var count = offsets[ oi ].count;
+					var index = offsets[ oi ].index;
+
+					for ( var i = start, il = start + count; i < il; i++ ) {
+
+						var a = index + indices[ i ];
+
+						position.set(
+							positions[ a * 3 ],
+							positions[ a * 3 + 1 ],
+							positions[ a * 3 + 2 ]
+						);
+						
+						testPoint( position, a );
+
+					}
+
+				}
+
+			} else {
+
+				var pointCount = positions.length / 3;
+
+				for ( var i = 0; i < pointCount; i ++ ) {
+
+					position.set(
+						positions[ 3 * i ],
+						positions[ 3 * i + 1 ],
+						positions[ 3 * i + 2 ]
+					);
+
+					testPoint( position, i );
+
+				}
+
+			}
+
+		} else {
+
+			var vertices = this.geometry.vertices;
+
+			for ( var i = 0; i < vertices.length; i ++ ) {
+
+				testPoint( vertices[ i ], i );
+
+			}
+
+		}
+
+	};
+
+}() );
+
 THREE.PointCloud.prototype.clone = function ( object ) {
 
 	if ( object === undefined ) object = new THREE.PointCloud( this.geometry, this.material );
@@ -31,7 +162,7 @@ THREE.PointCloud.prototype.clone = function ( object ) {
 
 THREE.ParticleSystem = function ( geometry, material ) {
 
-	console.warn( 'THREE.ParticleSystem has been DEPRECATED. Use THREE.PointCloud instead.' );
+	console.warn( 'THREE.ParticleSystem has been renamed to THREE.PointCloud.' );
 	return new THREE.PointCloud( geometry, material );
 
-};
+};

+ 28 - 3
src/objects/Sprite.js

@@ -23,9 +23,34 @@ THREE.Sprite = ( function () {
 
 THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );
 
-/*
- * Custom update matrix
- */
+THREE.Sprite.prototype.raycast = ( function () {
+
+	var matrixPosition = new THREE.Vector3();
+
+	return function ( raycaster, intersects ) {
+
+		matrixPosition.setFromMatrixPosition( this.matrixWorld );
+		
+		var distance = raycaster.ray.distanceToPoint( matrixPosition );
+
+		if ( distance > this.scale.x ) {
+
+			return;
+
+		}
+
+		intersects.push( {
+
+			distance: distance,
+			point: this.position,
+			face: null,
+			object: this
+
+		} );
+		
+	};
+
+}() );
 
 THREE.Sprite.prototype.updateMatrix = function () {
 

+ 1 - 1
src/renderers/CanvasRenderer.js

@@ -178,7 +178,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 	this.setClearColorHex = function ( hex, alpha ) {
 
-		console.warn( 'DEPRECATED: .setClearColorHex() is being removed. Use .setClearColor() instead.' );
+		console.warn( 'THREE.CanvasRenderer: .setClearColorHex() is being removed. Use .setClearColor() instead.' );
 		this.setClearColor( hex, alpha );
 
 	};

+ 4 - 4
src/renderers/WebGLRenderer.js

@@ -238,12 +238,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 		if ( mediumpAvailable ) {
 
 			_precision = "mediump";
-			console.warn( "WebGLRenderer: highp not supported, using mediump" );
+			console.warn( 'THREE.WebGLRenderer: highp not supported, using mediump.' );
 
 		} else {
 
 			_precision = "lowp";
-			console.warn( "WebGLRenderer: highp and mediump not supported, using lowp" );
+			console.warn( 'THREE.WebGLRenderer: highp and mediump not supported, using lowp.' );
 
 		}
 
@@ -252,7 +252,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 	if ( _precision === "mediump" && ! mediumpAvailable ) {
 
 		_precision = "lowp";
-		console.warn( "WebGLRenderer: mediump not supported, using lowp" );
+		console.warn( 'THREE.WebGLRenderer: mediump not supported, using lowp.' );
 
 	}
 
@@ -358,7 +358,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	this.setClearColorHex = function ( hex, alpha ) {
 
-		console.warn( 'DEPRECATED: .setClearColorHex() is being removed. Use .setClearColor() instead.' );
+		console.warn( 'THREE.WebGLRenderer: .setClearColorHex() is being removed. Use .setClearColor() instead.' );
 		this.setClearColor( hex, alpha );
 
 	};

+ 1 - 1
src/renderers/renderables/RenderableFace.js

@@ -15,7 +15,7 @@ THREE.RenderableFace = function () {
 	this.vertexNormalsModel = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
 	this.vertexNormalsLength = 0;
 
-	this.color = null;
+	this.color = new THREE.Color();
 	this.material = null;
 	this.uvs = [ new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() ];
 

+ 46 - 51
src/renderers/shaders/ShaderChunk.js

@@ -406,7 +406,7 @@ THREE.ShaderChunk = {
 		"		vec2 st0 = dFdx( vUv.st );",
 		"		vec2 st1 = dFdy( vUv.st );",
 
-		"		vec3 S = normalize(  q0 * st1.t - q1 * st0.t );",
+		"		vec3 S = normalize( q0 * st1.t - q1 * st0.t );",
 		"		vec3 T = normalize( -q0 * st1.s + q1 * st0.s );",
 		"		vec3 N = normalize( surf_norm );",
 
@@ -812,7 +812,7 @@ THREE.ShaderChunk = {
 
 		"#if MAX_POINT_LIGHTS > 0",
 
-		"	vec3 pointDiffuse  = vec3( 0.0 );",
+		"	vec3 pointDiffuse = vec3( 0.0 );",
 		"	vec3 pointSpecular = vec3( 0.0 );",
 
 		"	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
@@ -843,7 +843,7 @@ THREE.ShaderChunk = {
 
 		"		#endif",
 
-		"		pointDiffuse  += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;",
+		"		pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;",
 
 				// specular
 
@@ -851,9 +851,7 @@ THREE.ShaderChunk = {
 		"		float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
 		"		float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
 
-				// 2.0 => 2.0001 is hack to work around ANGLE bug
-
-		"		float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+		"		float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 		"		vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );",
 		"		pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;",
@@ -864,7 +862,7 @@ THREE.ShaderChunk = {
 
 		"#if MAX_SPOT_LIGHTS > 0",
 
-		"	vec3 spotDiffuse  = vec3( 0.0 );",
+		"	vec3 spotDiffuse = vec3( 0.0 );",
 		"	vec3 spotSpecular = vec3( 0.0 );",
 
 		"	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
@@ -909,9 +907,7 @@ THREE.ShaderChunk = {
 		"			float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
 		"			float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );",
 
-					// 2.0 => 2.0001 is hack to work around ANGLE bug
-
-		"			float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 		"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );",
 		"			spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;",
@@ -924,7 +920,7 @@ THREE.ShaderChunk = {
 
 		"#if MAX_DIR_LIGHTS > 0",
 
-		"	vec3 dirDiffuse  = vec3( 0.0 );",
+		"	vec3 dirDiffuse = vec3( 0.0 );",
 		"	vec3 dirSpecular = vec3( 0.0 );" ,
 
 		"	for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
@@ -949,38 +945,36 @@ THREE.ShaderChunk = {
 
 		"		#endif",
 
-		"		dirDiffuse  += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",
+		"		dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",
 
-				// specular
+		// specular
 
 		"		vec3 dirHalfVector = normalize( dirVector + viewPosition );",
 		"		float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
 		"		float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
 
-					/*
-				// fresnel term from skin shader
+		/*
+		// fresnel term from skin shader
 		"		const float F0 = 0.128;",
 
 		"		float base = 1.0 - dot( viewPosition, dirHalfVector );",
 		"		float exponential = pow( base, 5.0 );",
 
 		"		float fresnel = exponential + F0 * ( 1.0 - exponential );",
-				*/
+		*/
 
-				/*
-				// fresnel term from fresnel shader
+		/*
+		// fresnel term from fresnel shader
 		"		const float mFresnelBias = 0.08;",
 		"		const float mFresnelScale = 0.3;",
 		"		const float mFresnelPower = 5.0;",
 
 		"		float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );",
-				*/
-
-				// 2.0 => 2.0001 is hack to work around ANGLE bug
+		*/
 
-		"		float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+		"		float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
-				//"dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;",
+		// "		dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;",
 
 		"		vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );",
 		"		dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
@@ -992,7 +986,7 @@ THREE.ShaderChunk = {
 
 		"#if MAX_HEMI_LIGHTS > 0",
 
-		"	vec3 hemiDiffuse  = vec3( 0.0 );",
+		"	vec3 hemiDiffuse = vec3( 0.0 );",
 		"	vec3 hemiSpecular = vec3( 0.0 );" ,
 
 		"	for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
@@ -1000,7 +994,7 @@ THREE.ShaderChunk = {
 		"		vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );",
 		"		vec3 lVector = normalize( lDirection.xyz );",
 
-				// diffuse
+		// diffuse
 
 		"		float dotProduct = dot( normal, lVector );",
 		"		float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
@@ -1009,13 +1003,13 @@ THREE.ShaderChunk = {
 
 		"		hemiDiffuse += diffuse * hemiColor;",
 
-				// specular (sky light)
+		// specular (sky light)
 
 		"		vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
 		"		float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
 		"		float hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",
 
-				// specular (ground light)
+		// specular (ground light)
 
 		"		vec3 lVectorGround = -lVector;",
 
@@ -1025,9 +1019,7 @@ THREE.ShaderChunk = {
 
 		"		float dotProductGround = dot( normal, lVectorGround );",
 
-				// 2.0 => 2.0001 is hack to work around ANGLE bug
-
-		"		float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+		"		float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 		"		vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );",
 		"		vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );",
@@ -1210,10 +1202,11 @@ THREE.ShaderChunk = {
 
 		"	#endif",
 
-		"	vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
-		"	skinned      += boneMatY * skinVertex * skinWeight.y;",
-		"	skinned      += boneMatZ * skinVertex * skinWeight.z;",
-		"	skinned      += boneMatW * skinVertex * skinWeight.w;",
+		"	vec4 skinned = vec4( 0.0 );",
+		"	skinned += boneMatX * skinVertex * skinWeight.x;",
+		"	skinned += boneMatY * skinVertex * skinWeight.y;",
+		"	skinned += boneMatZ * skinVertex * skinWeight.z;",
+		"	skinned += boneMatW * skinVertex * skinWeight.w;",
 
 		"#endif"
 
@@ -1296,10 +1289,10 @@ THREE.ShaderChunk = {
 
 		"	vec3 morphedNormal = vec3( 0.0 );",
 
-		"	morphedNormal +=  ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];",
-		"	morphedNormal +=  ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];",
-		"	morphedNormal +=  ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];",
-		"	morphedNormal +=  ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];",
+		"	morphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];",
+		"	morphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];",
+		"	morphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];",
+		"	morphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];",
 
 		"	morphedNormal += normal;",
 
@@ -1311,10 +1304,11 @@ THREE.ShaderChunk = {
 
 		"#ifdef USE_SKINNING",
 
-		"	mat4 skinMatrix = skinWeight.x * boneMatX;",
-		"	skinMatrix 	+= skinWeight.y * boneMatY;",
-		"	skinMatrix 	+= skinWeight.z * boneMatZ;",
-		"	skinMatrix 	+= skinWeight.w * boneMatW;",
+		"	mat4 skinMatrix = mat4( 0.0 );",
+		"	skinMatrix += skinWeight.x * boneMatX;",
+		"	skinMatrix += skinWeight.y * boneMatY;",
+		"	skinMatrix += skinWeight.z * boneMatZ;",
+		"	skinMatrix += skinWeight.w * boneMatW;",
 
 		"	#ifdef USE_MORPHNORMALS",
 
@@ -1365,8 +1359,8 @@ THREE.ShaderChunk = {
 	// SHADOW MAP
 
 	// based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples
-	//  http://spidergl.org/example.php?id=6
-	// 	http://fabiensanglard.net/shadowmapping
+	// http://spidergl.org/example.php?id=6
+	// http://fabiensanglard.net/shadowmapping
 
 	shadowmap_pars_fragment: [
 
@@ -1418,8 +1412,8 @@ THREE.ShaderChunk = {
 
 		"		vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",
 
-				// "if ( something && something )" 		 breaks ATI OpenGL shader compiler
-				// "if ( all( something, something ) )"  using this instead
+				// "if ( something && something )" breaks ATI OpenGL shader compiler
+				// "if ( all( something, something ) )" using this instead
 
 		"		bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );",
 		"		bool inFrustum = all( inFrustumVec );",
@@ -1453,7 +1447,7 @@ THREE.ShaderChunk = {
 
 		"				float shadow = 0.0;",
 
-						/*
+		/*
 						// nested loops breaks shader compiler / validator on some ATI cards when using OpenGL
 						// must enroll loop manually
 
@@ -1474,7 +1468,7 @@ THREE.ShaderChunk = {
 
 		"				shadow /= 9.0;",
 
-						*/
+		*/
 
 		"				const float shadowDelta = 1.0 / 9.0;",
 
@@ -1576,13 +1570,13 @@ THREE.ShaderChunk = {
 
 		"				if ( fDepth < shadowCoord.z )",
 
-							// spot with multiple shadows is darker
+		// spot with multiple shadows is darker
 
 		"					shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );",
 
-							// spot with multiple shadows has the same color as single shadow spot
+		// spot with multiple shadows has the same color as single shadow spot
 
-							//"shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );",
+		// "					shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );",
 
 		"			#endif",
 
@@ -1728,6 +1722,7 @@ THREE.ShaderChunk = {
 	].join('\n'),
 
 	logdepthbuf_fragment: [
+
 		"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)",
 
 		"	gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;",

+ 42 - 44
src/renderers/shaders/ShaderLib.js

@@ -337,7 +337,7 @@ THREE.ShaderLib = {
 
 	'particle_basic': {
 
-		uniforms:  THREE.UniformsUtils.merge( [
+		uniforms: THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "particle" ],
 			THREE.UniformsLib[ "shadowmap" ]
@@ -411,8 +411,8 @@ THREE.ShaderLib = {
 			THREE.UniformsLib[ "fog" ],
 
 			{
-				"scale":     { type: "f", value: 1 },
-				"dashSize":  { type: "f", value: 1 },
+				"scale"    : { type: "f", value: 1 },
+				"dashSize" : { type: "f", value: 1 },
 				"totalSize": { type: "f", value: 2 }
 			}
 
@@ -596,18 +596,18 @@ THREE.ShaderLib = {
 
 			{
 
-			"enableAO"		  : { type: "i", value: 0 },
-			"enableDiffuse"	  : { type: "i", value: 0 },
-			"enableSpecular"  : { type: "i", value: 0 },
-			"enableReflection": { type: "i", value: 0 },
+			"enableAO"          : { type: "i", value: 0 },
+			"enableDiffuse"     : { type: "i", value: 0 },
+			"enableSpecular"    : { type: "i", value: 0 },
+			"enableReflection"  : { type: "i", value: 0 },
 			"enableDisplacement": { type: "i", value: 0 },
 
 			"tDisplacement": { type: "t", value: null }, // must go first as this is vertex texture
-			"tDiffuse"	   : { type: "t", value: null },
-			"tCube"		   : { type: "t", value: null },
-			"tNormal"	   : { type: "t", value: null },
-			"tSpecular"	   : { type: "t", value: null },
-			"tAO"		   : { type: "t", value: null },
+			"tDiffuse"     : { type: "t", value: null },
+			"tCube"        : { type: "t", value: null },
+			"tNormal"      : { type: "t", value: null },
+			"tSpecular"    : { type: "t", value: null },
+			"tAO"          : { type: "t", value: null },
 
 			"uNormalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) },
 
@@ -627,7 +627,7 @@ THREE.ShaderLib = {
 			"uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) },
 			"uRepeat" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
 
-			"wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
+			"wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
 
 			}
 
@@ -814,9 +814,7 @@ THREE.ShaderLib = {
 			"			float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
 			"			float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
 
-						// 2.0 => 2.0001 is hack to work around ANGLE bug
-
-			"			float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+			"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 			"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( pointVector, pointHalfVector ), 5.0 );",
 			"			pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
@@ -872,9 +870,7 @@ THREE.ShaderLib = {
 			"				float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
 			"				float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, shininess ), 0.0 );",
 
-							// 2.0 => 2.0001 is hack to work around ANGLE bug
-
-			"				float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+			"				float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 			"				vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );",
 			"				spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
@@ -920,9 +916,7 @@ THREE.ShaderLib = {
 			"			float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
 			"			float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
 
-						// 2.0 => 2.0001 is hack to work around ANGLE bug
-
-			"			float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+			"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 			"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
 			"			dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
@@ -935,7 +929,7 @@ THREE.ShaderLib = {
 
 			"	#if MAX_HEMI_LIGHTS > 0",
 
-			"		vec3 hemiDiffuse  = vec3( 0.0 );",
+			"		vec3 hemiDiffuse = vec3( 0.0 );",
 			"		vec3 hemiSpecular = vec3( 0.0 );" ,
 
 			"		for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
@@ -969,9 +963,7 @@ THREE.ShaderLib = {
 
 			"			float dotProductGround = dot( normal, lVectorGround );",
 
-						// 2.0 => 2.0001 is hack to work around ANGLE bug
-
-			"			float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+			"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 			"			vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
 			"			vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
@@ -1131,12 +1123,13 @@ THREE.ShaderLib = {
 
 			"				vec4 skinVertex = vec4( position, 1.0 );",
 
-			"				vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
-			"				skinned 	  += boneMatY * skinVertex * skinWeight.y;",
-			"				skinned 	  += boneMatZ * skinVertex * skinWeight.z;",
-			"				skinned 	  += boneMatW * skinVertex * skinWeight.w;",
+			"				vec4 skinned = vec4( 0.0 );",
+			"				skinned += boneMatX * skinVertex * skinWeight.x;",
+			"				skinned += boneMatY * skinVertex * skinWeight.y;",
+			"				skinned += boneMatZ * skinVertex * skinWeight.z;",
+			"				skinned += boneMatW * skinVertex * skinWeight.w;",
 
-			"				displacedPosition  = skinned.xyz;",
+			"				displacedPosition = skinned.xyz;",
 
 			"			#else",
 
@@ -1152,12 +1145,13 @@ THREE.ShaderLib = {
 
 			"			vec4 skinVertex = vec4( position, 1.0 );",
 
-			"			vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
-			"			skinned 	  += boneMatY * skinVertex * skinWeight.y;",
-			"			skinned 	  += boneMatZ * skinVertex * skinWeight.z;",
-			"			skinned 	  += boneMatW * skinVertex * skinWeight.w;",
+			"			vec4 skinned = vec4( 0.0 );",
+			"			skinned += boneMatX * skinVertex * skinWeight.x;",
+			"			skinned += boneMatY * skinVertex * skinWeight.y;",
+			"			skinned += boneMatZ * skinVertex * skinWeight.z;",
+			"			skinned += boneMatW * skinVertex * skinWeight.w;",
 
-			"			displacedPosition  = skinned.xyz;",
+			"			displacedPosition = skinned.xyz;",
 
 			"		#else",
 
@@ -1248,13 +1242,17 @@ THREE.ShaderLib = {
 
 	},
 
-	// Depth encoding into RGBA texture
-	// 	based on SpiderGL shadow map example
-	// 		http://spidergl.org/example.php?id=6
-	// 	originally from
-	//		http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
-	// 	see also here:
-	//		http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
+	/* Depth encoding into RGBA texture
+	 *
+	 * based on SpiderGL shadow map example
+	 * http://spidergl.org/example.php?id=6
+	 *
+	 * originally from
+	 * http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
+	 *
+	 * see also
+	 * http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
+	 */
 
 	'depthRGBA': {
 
@@ -1285,7 +1283,7 @@ THREE.ShaderLib = {
 			"vec4 pack_depth( const in float depth ) {",
 
 			"	const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
-			"	const vec4 bit_mask  = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
+			"	const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
 			"	vec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );", // "	vec4 res = fract( depth * bit_shift );",
 			"	res -= res.xxyz * bit_mask;",
 			"	return res;",

+ 1 - 1
src/renderers/webgl/WebGLProgram.js

@@ -277,7 +277,7 @@ THREE.WebGLProgram = ( function () {
 
 		if ( _gl.getProgramParameter( program, _gl.LINK_STATUS ) === false ) {
 
-			console.error( 'Could not initialise shader' );
+			console.error( 'THREE.WebGLProgram: Could not initialise shader.' );
 			console.error( 'gl.VALIDATE_STATUS', _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) );
 			console.error( 'gl.getError()', _gl.getError() );
 

+ 2 - 1
utils/build/externs/common.js

@@ -1,2 +1,3 @@
 var console;
-var JSON;
+var module;
+var JSON;

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

@@ -29,6 +29,7 @@
 	"src/core/BufferGeometry.js",
 	"src/core/Geometry.js",
 	"src/cameras/Camera.js",
+	"src/cameras/CubeCamera.js",
 	"src/cameras/OrthographicCamera.js",
 	"src/cameras/PerspectiveCamera.js",
 	"src/lights/Light.js",

+ 0 - 2
utils/build/includes/extras.json

@@ -23,8 +23,6 @@
 	"src/extras/animation/Animation.js",
 	"src/extras/animation/KeyFrameAnimation.js",
 	"src/extras/animation/MorphAnimation.js",
-	"src/extras/cameras/CubeCamera.js",
-	"src/extras/cameras/CombinedCamera.js",
 	"src/extras/geometries/BoxGeometry.js",
 	"src/extras/geometries/CircleGeometry.js",
 	"src/extras/geometries/CubeGeometry.js",

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

@@ -27,6 +27,7 @@
 	"src/core/BufferAttribute.js",
 	"src/core/BufferGeometry.js",
 	"src/cameras/Camera.js",
+	"src/cameras/CubeCamera.js",
 	"src/cameras/OrthographicCamera.js",
 	"src/cameras/PerspectiveCamera.js",
 	"src/lights/Light.js",

Some files were not shown because too many files changed in this diff