Prechádzať zdrojové kódy

update mesh.raycast to support instancedmesh.raycast,
update webgl_instancing_raycast and add webgl_instancing_morphtargets_raycast.

webglzhang 5 rokov pred
rodič
commit
645aea36e2

+ 186 - 442
build/three.js

@@ -11031,6 +11031,10 @@
 	var _ray = new Ray();
 	var _sphere = new Sphere();
 
+	var _matrixWorld = new Matrix4();
+	var _instanceMatrix = new Matrix4();
+	var _executionTimes = 1;
+
 	var _vA = new Vector3();
 	var _vB = new Vector3();
 	var _vC = new Vector3();
@@ -11153,163 +11157,194 @@
 
 			if ( material === undefined ) { return; }
 
-			// Checking boundingSphere distance to ray
+			//Determine how many times raycast will execute
 
-			if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
+			if ( this.isInstancedMesh ) {
 
-			_sphere.copy( geometry.boundingSphere );
-			_sphere.applyMatrix4( matrixWorld );
+				_executionTimes = this.count;
 
-			if ( raycaster.ray.intersectsSphere( _sphere ) === false ) { return; }
+			} else {
 
-			//
+				_executionTimes = 1;
 
-			_inverseMatrix.getInverse( matrixWorld );
-			_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
+			}
 
-			// Check boundingBox before continuing
+			for ( var instanceId = 0; instanceId < _executionTimes; instanceId ++ ) {
 
-			if ( geometry.boundingBox !== null ) {
+				//Determine the world matrix for this calculation
 
-				if ( _ray.intersectsBox( geometry.boundingBox ) === false ) { return; }
+				if ( this.isInstancedMesh ) {
 
-			}
+					_instanceMatrix = this.getMatrixAt( instanceId );
+					_matrixWorld.multiplyMatrices( matrixWorld, _instanceMatrix );
 
-			// check unsupported draw modes
+				} else {
 
-			if ( this.drawMode !== TrianglesDrawMode ) {
+					_matrixWorld = matrixWorld;
 
-				console.warn( 'THREE.Mesh: TriangleStripDrawMode and TriangleFanDrawMode are not supported by .raycast().' );
-				return;
+				}
 
-			}
+				// Checking boundingSphere distance to ray
 
-			var intersection;
+				if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
 
-			if ( geometry.isBufferGeometry ) {
+				_sphere.copy( geometry.boundingSphere );
+				_sphere.applyMatrix4( _matrixWorld );
 
-				var a, b, c;
-				var index = geometry.index;
-				var position = geometry.attributes.position;
-				var morphPosition = geometry.morphAttributes.position;
-				var morphTargetsRelative = geometry.morphTargetsRelative;
-				var uv = geometry.attributes.uv;
-				var uv2 = geometry.attributes.uv2;
-				var groups = geometry.groups;
-				var drawRange = geometry.drawRange;
-				var i, j, il, jl;
-				var group, groupMaterial;
-				var start, end;
+				if ( raycaster.ray.intersectsSphere( _sphere ) === false ) { continue; }
 
-				if ( index !== null ) {
+				//Transform the ray into the local space of the model
 
-					// indexed buffer geometry
+				_inverseMatrix.getInverse( _matrixWorld );
+				_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
 
-					if ( Array.isArray( material ) ) {
+				// Check boundingBox before continuing
 
-						for ( i = 0, il = groups.length; i < il; i ++ ) {
+				if ( geometry.boundingBox !== null ) {
 
-							group = groups[ i ];
-							groupMaterial = material[ group.materialIndex ];
+					if ( _ray.intersectsBox( geometry.boundingBox ) === false ) { continue; }
 
-							start = Math.max( group.start, drawRange.start );
-							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+				}
 
-							for ( j = start, jl = end; j < jl; j += 3 ) {
+				var intersection;
 
-								a = index.getX( j );
-								b = index.getX( j + 1 );
-								c = index.getX( j + 2 );
+				if ( geometry.isBufferGeometry ) {
 
-								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+					var a, b, c;
+					var index = geometry.index;
+					var position = geometry.attributes.position;
+					var morphPosition = geometry.morphAttributes.position;
+					var uv = geometry.attributes.uv;
+					var uv2 = geometry.attributes.uv2;
+					var groups = geometry.groups;
+					var drawRange = geometry.drawRange;
+					var i, j, il, jl;
+					var group, groupMaterial;
+					var start, end;
 
-								if ( intersection ) {
+					if ( index !== null ) {
 
-									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
-									intersection.face.materialIndex = group.materialIndex;
-									intersects.push( intersection );
+						// indexed buffer geometry
+
+						if ( Array.isArray( material ) ) {
+
+							for ( i = 0, il = groups.length; i < il; i ++ ) {
+
+								group = groups[ i ];
+								groupMaterial = material[ group.materialIndex ];
+
+								start = Math.max( group.start, drawRange.start );
+								end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+
+								for ( j = start, jl = end; j < jl; j += 3 ) {
+
+									a = index.getX( j );
+									b = index.getX( j + 1 );
+									c = index.getX( j + 2 );
+
+									intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
+
+									if ( intersection ) {
+
+										intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
+										intersection.face.materialIndex = group.materialIndex;
+
+										intersection.instanceId = instanceId;
+
+										intersects.push( intersection );
+
+									}
 
 								}
 
 							}
 
-						}
+						} else {
 
-					} else {
+							start = Math.max( 0, drawRange.start );
+							end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
 
-						start = Math.max( 0, drawRange.start );
-						end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
+							for ( i = start, il = end; i < il; i += 3 ) {
 
-						for ( i = start, il = end; i < il; i += 3 ) {
+								a = index.getX( i );
+								b = index.getX( i + 1 );
+								c = index.getX( i + 2 );
+
+								intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
+
+								if ( intersection ) {
 
-							a = index.getX( i );
-							b = index.getX( i + 1 );
-							c = index.getX( i + 2 );
+									intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
 
-							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+									intersection.instanceId = instanceId;
 
-							if ( intersection ) {
+									intersects.push( intersection );
 
-								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
-								intersects.push( intersection );
+								}
 
 							}
 
 						}
 
-					}
+					} else if ( position !== undefined ) {
 
-				} else if ( position !== undefined ) {
+						// non-indexed buffer geometry
 
-					// non-indexed buffer geometry
+						if ( Array.isArray( material ) ) {
 
-					if ( Array.isArray( material ) ) {
+							for ( i = 0, il = groups.length; i < il; i ++ ) {
 
-						for ( i = 0, il = groups.length; i < il; i ++ ) {
+								group = groups[ i ];
+								groupMaterial = material[ group.materialIndex ];
 
-							group = groups[ i ];
-							groupMaterial = material[ group.materialIndex ];
+								start = Math.max( group.start, drawRange.start );
+								end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
 
-							start = Math.max( group.start, drawRange.start );
-							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+								for ( j = start, jl = end; j < jl; j += 3 ) {
 
-							for ( j = start, jl = end; j < jl; j += 3 ) {
+									a = j;
+									b = j + 1;
+									c = j + 2;
 
-								a = j;
-								b = j + 1;
-								c = j + 2;
+									intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
 
-								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+									if ( intersection ) {
 
-								if ( intersection ) {
+										intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
+										intersection.face.materialIndex = group.materialIndex;
 
-									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
-									intersection.face.materialIndex = group.materialIndex;
-									intersects.push( intersection );
+										intersection.instanceId = instanceId;
+
+										intersects.push( intersection );
+
+									}
 
 								}
 
 							}
 
-						}
+						} else {
 
-					} else {
+							start = Math.max( 0, drawRange.start );
+							end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
 
-						start = Math.max( 0, drawRange.start );
-						end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
+							for ( i = start, il = end; i < il; i += 3 ) {
 
-						for ( i = start, il = end; i < il; i += 3 ) {
+								a = i;
+								b = i + 1;
+								c = i + 2;
+
+								intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
 
-							a = i;
-							b = i + 1;
-							c = i + 2;
+								if ( intersection ) {
+
+									intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
 
-							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+									intersection.instanceId = instanceId;
 
-							if ( intersection ) {
+									intersects.push( intersection );
 
-								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
-								intersects.push( intersection );
+								}
 
 							}
 
@@ -11317,49 +11352,49 @@
 
 					}
 
-				}
+				} else if ( geometry.isGeometry ) {
 
-			} else if ( geometry.isGeometry ) {
+					var fvA, fvB, fvC;
+					var isMultiMaterial = Array.isArray( material );
 
-				var fvA, fvB, fvC;
-				var isMultiMaterial = Array.isArray( material );
+					var vertices = geometry.vertices;
+					var faces = geometry.faces;
+					var uvs;
 
-				var vertices = geometry.vertices;
-				var faces = geometry.faces;
-				var uvs;
+					var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
+					if ( faceVertexUvs.length > 0 ) { uvs = faceVertexUvs; }
 
-				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
-				if ( faceVertexUvs.length > 0 ) { uvs = faceVertexUvs; }
+					for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
 
-				for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
+						var face = faces[ f ];
+						var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
 
-					var face = faces[ f ];
-					var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
+						if ( faceMaterial === undefined ) { continue; }
 
-					if ( faceMaterial === undefined ) { continue; }
+						fvA = vertices[ face.a ];
+						fvB = vertices[ face.b ];
+						fvC = vertices[ face.c ];
 
-					fvA = vertices[ face.a ];
-					fvB = vertices[ face.b ];
-					fvC = vertices[ face.c ];
+						intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
 
-					intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
+						if ( intersection ) {
 
-					if ( intersection ) {
+							if ( uvs && uvs[ f ] ) {
 
-						if ( uvs && uvs[ f ] ) {
+								var uvs_f = uvs[ f ];
+								_uvA.copy( uvs_f[ 0 ] );
+								_uvB.copy( uvs_f[ 1 ] );
+								_uvC.copy( uvs_f[ 2 ] );
 
-							var uvs_f = uvs[ f ];
-							_uvA.copy( uvs_f[ 0 ] );
-							_uvB.copy( uvs_f[ 1 ] );
-							_uvC.copy( uvs_f[ 2 ] );
+								intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
 
-							intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
+							}
 
-						}
+							intersection.face = face;
+							intersection.faceIndex = f;
+							intersects.push( intersection );
 
-						intersection.face = face;
-						intersection.faceIndex = f;
-						intersects.push( intersection );
+						}
 
 					}
 
@@ -11394,7 +11429,7 @@
 		if ( intersect === null ) { return null; }
 
 		_intersectionPointWorld.copy( point );
-		_intersectionPointWorld.applyMatrix4( object.matrixWorld );
+		_intersectionPointWorld.applyMatrix4( _matrixWorld );
 
 		var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );
 
@@ -11408,7 +11443,7 @@
 
 	}
 
-	function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {
+	function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) {
 
 		_vA.fromBufferAttribute( position, a );
 		_vB.fromBufferAttribute( position, b );
@@ -11433,19 +11468,9 @@
 				_tempB.fromBufferAttribute( morphAttribute, b );
 				_tempC.fromBufferAttribute( morphAttribute, c );
 
-				if ( morphTargetsRelative ) {
-
-					_morphA.addScaledVector( _tempA, influence );
-					_morphB.addScaledVector( _tempB, influence );
-					_morphC.addScaledVector( _tempC, influence );
-
-				} else {
-
-					_morphA.addScaledVector( _tempA.sub( _vA ), influence );
-					_morphB.addScaledVector( _tempB.sub( _vB ), influence );
-					_morphC.addScaledVector( _tempC.sub( _vC ), influence );
-
-				}
+				_morphA.addScaledVector( _tempA.sub( _vA ), influence );
+				_morphB.addScaledVector( _tempB.sub( _vB ), influence );
+				_morphC.addScaledVector( _tempC.sub( _vC ), influence );
 
 			}
 
@@ -27296,21 +27321,6 @@
 	 * @author mrdoob / http://mrdoob.com/
 	 */
 
-	var _inverseMatrix$1 = new Matrix4();
-	var _ray$1 = new Ray();
-	var _sphere$2 = new Sphere();
-
-	var _vA$2 = new Vector3();
-	var _vB$2 = new Vector3();
-	var _vC$2 = new Vector3();
-
-	var _uvA$2 = new Vector2();
-	var _uvB$2 = new Vector2();
-	var _uvC$2 = new Vector2();
-
-	var _intersectionPoint$1 = new Vector3();
-	var _intersectionPointWorld$1 = new Vector3();
-
 	function InstancedMesh( geometry, material, count ) {
 
 		Mesh.call( this, geometry, material );
@@ -27327,203 +27337,9 @@
 
 		isInstancedMesh: true,
 
-		raycast: function ( raycaster, intersects ) {
-
-			var geometry = this.geometry;
-			var material = this.material;
-			var matrixWorld = this.matrixWorld;
-
-			if ( material === undefined ) { return; }
-
-			for ( var instanceID = 0; instanceID < this.count; instanceID ++ ) {
-
-				//Calculate the world matrix for each instance
-
-				var instanceMatrixWorld = new Matrix4();
-
-				var instanceMatrix = this.getMatrixAt( instanceID );
-
-				instanceMatrixWorld.multiplyMatrices( matrixWorld, instanceMatrix );
-
-				// Checking boundingSphere distance to ray
-
-				if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
-
-				_sphere$2.copy( geometry.boundingSphere );
-				_sphere$2.applyMatrix4( instanceMatrixWorld );
-
-				if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) { continue; }
-
-				//Transform the ray into the local space of the model
-
-				_inverseMatrix$1.getInverse( instanceMatrixWorld );
-				_ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );
-
-				// Check boundingBox before continuing
-
-				if ( geometry.boundingBox !== null ) {
-
-					if ( _ray$1.intersectsBox( geometry.boundingBox ) === false ) { continue; }
-
-				}
-
-				var intersection;
-
-				if ( geometry.isBufferGeometry ) {
-
-					var a, b, c;
-					var index = geometry.index;
-					var position = geometry.attributes.position;
-					var uv = geometry.attributes.uv;
-					var uv2 = geometry.attributes.uv2;
-					var groups = geometry.groups;
-					var drawRange = geometry.drawRange;
-					var i, j, il, jl;
-					var group, groupMaterial;
-					var start, end;
-
-					if ( index !== null ) {
-
-						// indexed buffer geometry
-
-						if ( Array.isArray( material ) ) {
-
-							for ( i = 0, il = groups.length; i < il; i ++ ) {
-
-								group = groups[ i ];
-								groupMaterial = material[ group.materialIndex ];
-
-								start = Math.max( group.start, drawRange.start );
-								end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
-
-								for ( j = start, jl = end; j < jl; j += 3 ) {
-
-									a = index.getX( j );
-									b = index.getX( j + 1 );
-									c = index.getX( j + 2 );
-
-									intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, groupMaterial, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-									if ( intersection ) {
-
-										intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
-										intersection.face.materialIndex = group.materialIndex;
-
-										intersection.instanceID = instanceID;
-
-										intersects.push( intersection );
-
-									}
-
-								}
-
-							}
-
-						} else {
-
-							start = Math.max( 0, drawRange.start );
-							end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
-
-							for ( i = start, il = end; i < il; i += 3 ) {
-
-								a = index.getX( i );
-								b = index.getX( i + 1 );
-								c = index.getX( i + 2 );
-
-								intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, material, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-								if ( intersection ) {
-
-									intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
-
-									intersection.instanceID = instanceID;
-
-									intersects.push( intersection );
-
-								}
-
-							}
-
-						}
-
-					} else if ( position !== undefined ) {
-
-						// non-indexed buffer geometry
-
-						if ( Array.isArray( material ) ) {
-
-							for ( i = 0, il = groups.length; i < il; i ++ ) {
-
-								group = groups[ i ];
-								groupMaterial = material[ group.materialIndex ];
-
-								start = Math.max( group.start, drawRange.start );
-								end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
-
-								for ( j = start, jl = end; j < jl; j += 3 ) {
-
-									a = j;
-									b = j + 1;
-									c = j + 2;
-
-									intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, groupMaterial, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-									if ( intersection ) {
-
-										intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
-										intersection.face.materialIndex = group.materialIndex;
-
-										intersection.instanceID = instanceID;
-
-										intersects.push( intersection );
-
-									}
-
-								}
-
-							}
-
-						} else {
-
-							start = Math.max( 0, drawRange.start );
-							end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
-
-							for ( i = start, il = end; i < il; i += 3 ) {
-
-								a = i;
-								b = i + 1;
-								c = i + 2;
-
-								intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, material, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-								if ( intersection ) {
-
-									intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
+		getMatrixAt: function ( index, matrix ) {
 
-									intersection.instanceID = instanceID;
-
-									intersects.push( intersection );
-
-								}
-
-							}
-
-						}
-
-					}
-
-				}
-
-
-
-
-			}
-
-		},
-
-		getMatrixAt: function ( index ) {
-
-			var matrix = new Matrix4();
+			var matrix = matrix || new Matrix4();
 
 			matrix.fromArray( this.instanceMatrix.array, index * 16 );
 
@@ -27537,84 +27353,12 @@
 
 		},
 
-		updateMorphTargets: function () {
-
-		}
+		// updateMorphTargets: function () {
+	    //
+		// }
 
 	} );
 
-	function checkIntersection$1( object, matrixWorld, material, raycaster, ray, pA, pB, pC, point ) {
-
-		var intersect;
-
-		if ( material.side === BackSide ) {
-
-			intersect = ray.intersectTriangle( pC, pB, pA, true, point );
-
-		} else {
-
-			intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
-
-		}
-
-		if ( intersect === null ) { return null; }
-
-		_intersectionPointWorld$1.copy( point );
-		_intersectionPointWorld$1.applyMatrix4( matrixWorld );
-
-		var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld$1 );
-
-		if ( distance < raycaster.near || distance > raycaster.far ) { return null; }
-
-		return {
-			distance: distance,
-			point: _intersectionPointWorld$1.clone(),
-			object: object
-		};
-
-	}
-
-	function checkBufferGeometryIntersection$1( object, matrixWorld, material, raycaster, ray, position, uv, uv2, a, b, c ) {
-
-		_vA$2.fromBufferAttribute( position, a );
-		_vB$2.fromBufferAttribute( position, b );
-		_vC$2.fromBufferAttribute( position, c );
-
-		var intersection = checkIntersection$1( object, matrixWorld, material, raycaster, ray, _vA$2, _vB$2, _vC$2, _intersectionPoint$1 );
-
-		if ( intersection ) {
-
-			if ( uv ) {
-
-				_uvA$2.fromBufferAttribute( uv, a );
-				_uvB$2.fromBufferAttribute( uv, b );
-				_uvC$2.fromBufferAttribute( uv, c );
-
-				intersection.uv = Triangle.getUV( _intersectionPoint$1, _vA$2, _vB$2, _vC$2, _uvA$2, _uvB$2, _uvC$2, new Vector2() );
-
-			}
-
-			if ( uv2 ) {
-
-				_uvA$2.fromBufferAttribute( uv2, a );
-				_uvB$2.fromBufferAttribute( uv2, b );
-				_uvC$2.fromBufferAttribute( uv2, c );
-
-				intersection.uv2 = Triangle.getUV( _intersectionPoint$1, _vA$2, _vB$2, _vC$2, _uvA$2, _uvB$2, _uvC$2, new Vector2() );
-
-			}
-
-			var face = new Face3( a, b, c );
-			Triangle.getNormal( _vA$2, _vB$2, _vC$2, face.normal );
-
-			intersection.face = face;
-
-		}
-
-		return intersection;
-
-	}
-
 	/**
 	 * @author mrdoob / http://mrdoob.com/
 	 * @author alteredq / http://alteredqualia.com/
@@ -27670,9 +27414,9 @@
 
 	var _start = new Vector3();
 	var _end = new Vector3();
-	var _inverseMatrix$2 = new Matrix4();
-	var _ray$2 = new Ray();
-	var _sphere$3 = new Sphere();
+	var _inverseMatrix$1 = new Matrix4();
+	var _ray$1 = new Ray();
+	var _sphere$2 = new Sphere();
 
 	function Line( geometry, material, mode ) {
 
@@ -27759,16 +27503,16 @@
 
 			if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
 
-			_sphere$3.copy( geometry.boundingSphere );
-			_sphere$3.applyMatrix4( matrixWorld );
-			_sphere$3.radius += precision;
+			_sphere$2.copy( geometry.boundingSphere );
+			_sphere$2.applyMatrix4( matrixWorld );
+			_sphere$2.radius += precision;
 
-			if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) { return; }
+			if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) { return; }
 
 			//
 
-			_inverseMatrix$2.getInverse( matrixWorld );
-			_ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
+			_inverseMatrix$1.getInverse( matrixWorld );
+			_ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );
 
 			var localPrecision = precision / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
 			var localPrecisionSq = localPrecision * localPrecision;
@@ -27797,7 +27541,7 @@
 						vStart.fromArray( positions, a * 3 );
 						vEnd.fromArray( positions, b * 3 );
 
-						var distSq = _ray$2.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
+						var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
 
 						if ( distSq > localPrecisionSq ) { continue; }
 
@@ -27829,7 +27573,7 @@
 						vStart.fromArray( positions, 3 * i );
 						vEnd.fromArray( positions, 3 * i + 3 );
 
-						var distSq = _ray$2.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
+						var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
 
 						if ( distSq > localPrecisionSq ) { continue; }
 
@@ -27863,7 +27607,7 @@
 
 				for ( var i = 0; i < nbVertices - 1; i += step ) {
 
-					var distSq = _ray$2.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
+					var distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
 
 					if ( distSq > localPrecisionSq ) { continue; }
 
@@ -28061,9 +27805,9 @@
 	 * @author alteredq / http://alteredqualia.com/
 	 */
 
-	var _inverseMatrix$3 = new Matrix4();
-	var _ray$3 = new Ray();
-	var _sphere$4 = new Sphere();
+	var _inverseMatrix$2 = new Matrix4();
+	var _ray$2 = new Ray();
+	var _sphere$3 = new Sphere();
 	var _position$1 = new Vector3();
 
 	function Points( geometry, material ) {
@@ -28095,16 +27839,16 @@
 
 			if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
 
-			_sphere$4.copy( geometry.boundingSphere );
-			_sphere$4.applyMatrix4( matrixWorld );
-			_sphere$4.radius += threshold;
+			_sphere$3.copy( geometry.boundingSphere );
+			_sphere$3.applyMatrix4( matrixWorld );
+			_sphere$3.radius += threshold;
 
-			if ( raycaster.ray.intersectsSphere( _sphere$4 ) === false ) { return; }
+			if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) { return; }
 
 			//
 
-			_inverseMatrix$3.getInverse( matrixWorld );
-			_ray$3.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$3 );
+			_inverseMatrix$2.getInverse( matrixWorld );
+			_ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
 
 			var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
 			var localThresholdSq = localThreshold * localThreshold;
@@ -28211,13 +27955,13 @@
 
 	function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
 
-		var rayPointDistanceSq = _ray$3.distanceSqToPoint( point );
+		var rayPointDistanceSq = _ray$2.distanceSqToPoint( point );
 
 		if ( rayPointDistanceSq < localThresholdSq ) {
 
 			var intersectPoint = new Vector3();
 
-			_ray$3.closestPointToPoint( point, intersectPoint );
+			_ray$2.closestPointToPoint( point, intersectPoint );
 			intersectPoint.applyMatrix4( matrixWorld );
 
 			var distance = raycaster.ray.origin.distanceTo( intersectPoint );

+ 186 - 442
build/three.module.js

@@ -11025,6 +11025,10 @@ var _inverseMatrix = new Matrix4();
 var _ray = new Ray();
 var _sphere = new Sphere();
 
+var _matrixWorld = new Matrix4();
+var _instanceMatrix = new Matrix4();
+var _executionTimes = 1;
+
 var _vA = new Vector3();
 var _vB = new Vector3();
 var _vC = new Vector3();
@@ -11147,163 +11151,194 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		if ( material === undefined ) return;
 
-		// Checking boundingSphere distance to ray
+		//Determine how many times raycast will execute
 
-		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
+		if ( this.isInstancedMesh ) {
 
-		_sphere.copy( geometry.boundingSphere );
-		_sphere.applyMatrix4( matrixWorld );
+			_executionTimes = this.count;
 
-		if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return;
+		} else {
 
-		//
+			_executionTimes = 1;
 
-		_inverseMatrix.getInverse( matrixWorld );
-		_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
+		}
 
-		// Check boundingBox before continuing
+		for ( var instanceId = 0; instanceId < _executionTimes; instanceId ++ ) {
 
-		if ( geometry.boundingBox !== null ) {
+			//Determine the world matrix for this calculation
 
-			if ( _ray.intersectsBox( geometry.boundingBox ) === false ) return;
+			if ( this.isInstancedMesh ) {
 
-		}
+				_instanceMatrix = this.getMatrixAt( instanceId );
+				_matrixWorld.multiplyMatrices( matrixWorld, _instanceMatrix );
 
-		// check unsupported draw modes
+			} else {
 
-		if ( this.drawMode !== TrianglesDrawMode ) {
+				_matrixWorld = matrixWorld;
 
-			console.warn( 'THREE.Mesh: TriangleStripDrawMode and TriangleFanDrawMode are not supported by .raycast().' );
-			return;
+			}
 
-		}
+			// Checking boundingSphere distance to ray
 
-		var intersection;
+			if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
 
-		if ( geometry.isBufferGeometry ) {
+			_sphere.copy( geometry.boundingSphere );
+			_sphere.applyMatrix4( _matrixWorld );
 
-			var a, b, c;
-			var index = geometry.index;
-			var position = geometry.attributes.position;
-			var morphPosition = geometry.morphAttributes.position;
-			var morphTargetsRelative = geometry.morphTargetsRelative;
-			var uv = geometry.attributes.uv;
-			var uv2 = geometry.attributes.uv2;
-			var groups = geometry.groups;
-			var drawRange = geometry.drawRange;
-			var i, j, il, jl;
-			var group, groupMaterial;
-			var start, end;
+			if ( raycaster.ray.intersectsSphere( _sphere ) === false ) continue;
 
-			if ( index !== null ) {
+			//Transform the ray into the local space of the model
 
-				// indexed buffer geometry
+			_inverseMatrix.getInverse( _matrixWorld );
+			_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
 
-				if ( Array.isArray( material ) ) {
+			// Check boundingBox before continuing
 
-					for ( i = 0, il = groups.length; i < il; i ++ ) {
+			if ( geometry.boundingBox !== null ) {
 
-						group = groups[ i ];
-						groupMaterial = material[ group.materialIndex ];
+				if ( _ray.intersectsBox( geometry.boundingBox ) === false ) continue;
 
-						start = Math.max( group.start, drawRange.start );
-						end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+			}
 
-						for ( j = start, jl = end; j < jl; j += 3 ) {
+			var intersection;
 
-							a = index.getX( j );
-							b = index.getX( j + 1 );
-							c = index.getX( j + 2 );
+			if ( geometry.isBufferGeometry ) {
 
-							intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+				var a, b, c;
+				var index = geometry.index;
+				var position = geometry.attributes.position;
+				var morphPosition = geometry.morphAttributes.position;
+				var uv = geometry.attributes.uv;
+				var uv2 = geometry.attributes.uv2;
+				var groups = geometry.groups;
+				var drawRange = geometry.drawRange;
+				var i, j, il, jl;
+				var group, groupMaterial;
+				var start, end;
 
-							if ( intersection ) {
+				if ( index !== null ) {
 
-								intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
-								intersection.face.materialIndex = group.materialIndex;
-								intersects.push( intersection );
+					// indexed buffer geometry
+
+					if ( Array.isArray( material ) ) {
+
+						for ( i = 0, il = groups.length; i < il; i ++ ) {
+
+							group = groups[ i ];
+							groupMaterial = material[ group.materialIndex ];
+
+							start = Math.max( group.start, drawRange.start );
+							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+
+							for ( j = start, jl = end; j < jl; j += 3 ) {
+
+								a = index.getX( j );
+								b = index.getX( j + 1 );
+								c = index.getX( j + 2 );
+
+								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
+
+								if ( intersection ) {
+
+									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
+									intersection.face.materialIndex = group.materialIndex;
+
+									intersection.instanceId = instanceId;
+
+									intersects.push( intersection );
+
+								}
 
 							}
 
 						}
 
-					}
+					} else {
 
-				} else {
+						start = Math.max( 0, drawRange.start );
+						end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
 
-					start = Math.max( 0, drawRange.start );
-					end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
+						for ( i = start, il = end; i < il; i += 3 ) {
 
-					for ( i = start, il = end; i < il; i += 3 ) {
+							a = index.getX( i );
+							b = index.getX( i + 1 );
+							c = index.getX( i + 2 );
+
+							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
+
+							if ( intersection ) {
 
-						a = index.getX( i );
-						b = index.getX( i + 1 );
-						c = index.getX( i + 2 );
+								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
 
-						intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+								intersection.instanceId = instanceId;
 
-						if ( intersection ) {
+								intersects.push( intersection );
 
-							intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
-							intersects.push( intersection );
+							}
 
 						}
 
 					}
 
-				}
+				} else if ( position !== undefined ) {
 
-			} else if ( position !== undefined ) {
+					// non-indexed buffer geometry
 
-				// non-indexed buffer geometry
+					if ( Array.isArray( material ) ) {
 
-				if ( Array.isArray( material ) ) {
+						for ( i = 0, il = groups.length; i < il; i ++ ) {
 
-					for ( i = 0, il = groups.length; i < il; i ++ ) {
+							group = groups[ i ];
+							groupMaterial = material[ group.materialIndex ];
 
-						group = groups[ i ];
-						groupMaterial = material[ group.materialIndex ];
+							start = Math.max( group.start, drawRange.start );
+							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
 
-						start = Math.max( group.start, drawRange.start );
-						end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+							for ( j = start, jl = end; j < jl; j += 3 ) {
 
-						for ( j = start, jl = end; j < jl; j += 3 ) {
+								a = j;
+								b = j + 1;
+								c = j + 2;
 
-							a = j;
-							b = j + 1;
-							c = j + 2;
+								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
 
-							intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+								if ( intersection ) {
 
-							if ( intersection ) {
+									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
+									intersection.face.materialIndex = group.materialIndex;
 
-								intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
-								intersection.face.materialIndex = group.materialIndex;
-								intersects.push( intersection );
+									intersection.instanceId = instanceId;
+
+									intersects.push( intersection );
+
+								}
 
 							}
 
 						}
 
-					}
+					} else {
 
-				} else {
+						start = Math.max( 0, drawRange.start );
+						end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
 
-					start = Math.max( 0, drawRange.start );
-					end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
+						for ( i = start, il = end; i < il; i += 3 ) {
 
-					for ( i = start, il = end; i < il; i += 3 ) {
+							a = i;
+							b = i + 1;
+							c = i + 2;
+
+							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
 
-						a = i;
-						b = i + 1;
-						c = i + 2;
+							if ( intersection ) {
+
+								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
 
-						intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+								intersection.instanceId = instanceId;
 
-						if ( intersection ) {
+								intersects.push( intersection );
 
-							intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
-							intersects.push( intersection );
+							}
 
 						}
 
@@ -11311,49 +11346,49 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 				}
 
-			}
+			} else if ( geometry.isGeometry ) {
 
-		} else if ( geometry.isGeometry ) {
+				var fvA, fvB, fvC;
+				var isMultiMaterial = Array.isArray( material );
 
-			var fvA, fvB, fvC;
-			var isMultiMaterial = Array.isArray( material );
+				var vertices = geometry.vertices;
+				var faces = geometry.faces;
+				var uvs;
 
-			var vertices = geometry.vertices;
-			var faces = geometry.faces;
-			var uvs;
+				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
+				if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
 
-			var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
-			if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
+				for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
 
-			for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
+					var face = faces[ f ];
+					var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
 
-				var face = faces[ f ];
-				var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
+					if ( faceMaterial === undefined ) continue;
 
-				if ( faceMaterial === undefined ) continue;
+					fvA = vertices[ face.a ];
+					fvB = vertices[ face.b ];
+					fvC = vertices[ face.c ];
 
-				fvA = vertices[ face.a ];
-				fvB = vertices[ face.b ];
-				fvC = vertices[ face.c ];
+					intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
 
-				intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
+					if ( intersection ) {
 
-				if ( intersection ) {
+						if ( uvs && uvs[ f ] ) {
 
-					if ( uvs && uvs[ f ] ) {
+							var uvs_f = uvs[ f ];
+							_uvA.copy( uvs_f[ 0 ] );
+							_uvB.copy( uvs_f[ 1 ] );
+							_uvC.copy( uvs_f[ 2 ] );
 
-						var uvs_f = uvs[ f ];
-						_uvA.copy( uvs_f[ 0 ] );
-						_uvB.copy( uvs_f[ 1 ] );
-						_uvC.copy( uvs_f[ 2 ] );
+							intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
 
-						intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
+						}
 
-					}
+						intersection.face = face;
+						intersection.faceIndex = f;
+						intersects.push( intersection );
 
-					intersection.face = face;
-					intersection.faceIndex = f;
-					intersects.push( intersection );
+					}
 
 				}
 
@@ -11388,7 +11423,7 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point
 	if ( intersect === null ) return null;
 
 	_intersectionPointWorld.copy( point );
-	_intersectionPointWorld.applyMatrix4( object.matrixWorld );
+	_intersectionPointWorld.applyMatrix4( _matrixWorld );
 
 	var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );
 
@@ -11402,7 +11437,7 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point
 
 }
 
-function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {
+function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) {
 
 	_vA.fromBufferAttribute( position, a );
 	_vB.fromBufferAttribute( position, b );
@@ -11427,19 +11462,9 @@ function checkBufferGeometryIntersection( object, material, raycaster, ray, posi
 			_tempB.fromBufferAttribute( morphAttribute, b );
 			_tempC.fromBufferAttribute( morphAttribute, c );
 
-			if ( morphTargetsRelative ) {
-
-				_morphA.addScaledVector( _tempA, influence );
-				_morphB.addScaledVector( _tempB, influence );
-				_morphC.addScaledVector( _tempC, influence );
-
-			} else {
-
-				_morphA.addScaledVector( _tempA.sub( _vA ), influence );
-				_morphB.addScaledVector( _tempB.sub( _vB ), influence );
-				_morphC.addScaledVector( _tempC.sub( _vC ), influence );
-
-			}
+			_morphA.addScaledVector( _tempA.sub( _vA ), influence );
+			_morphB.addScaledVector( _tempB.sub( _vB ), influence );
+			_morphC.addScaledVector( _tempC.sub( _vC ), influence );
 
 		}
 
@@ -27288,21 +27313,6 @@ Bone.prototype = Object.assign( Object.create( Object3D.prototype ), {
  * @author mrdoob / http://mrdoob.com/
  */
 
-var _inverseMatrix$1 = new Matrix4();
-var _ray$1 = new Ray();
-var _sphere$2 = new Sphere();
-
-var _vA$2 = new Vector3();
-var _vB$2 = new Vector3();
-var _vC$2 = new Vector3();
-
-var _uvA$2 = new Vector2();
-var _uvB$2 = new Vector2();
-var _uvC$2 = new Vector2();
-
-var _intersectionPoint$1 = new Vector3();
-var _intersectionPointWorld$1 = new Vector3();
-
 function InstancedMesh( geometry, material, count ) {
 
 	Mesh.call( this, geometry, material );
@@ -27319,203 +27329,9 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	isInstancedMesh: true,
 
-	raycast: function ( raycaster, intersects ) {
-
-		var geometry = this.geometry;
-		var material = this.material;
-		var matrixWorld = this.matrixWorld;
-
-		if ( material === undefined ) return;
-
-		for ( var instanceID = 0; instanceID < this.count; instanceID ++ ) {
-
-			//Calculate the world matrix for each instance
-
-			var instanceMatrixWorld = new Matrix4();
-
-			var instanceMatrix = this.getMatrixAt( instanceID );
-
-			instanceMatrixWorld.multiplyMatrices( matrixWorld, instanceMatrix );
-
-			// Checking boundingSphere distance to ray
-
-			if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
-
-			_sphere$2.copy( geometry.boundingSphere );
-			_sphere$2.applyMatrix4( instanceMatrixWorld );
-
-			if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) continue;
-
-			//Transform the ray into the local space of the model
-
-			_inverseMatrix$1.getInverse( instanceMatrixWorld );
-			_ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );
-
-			// Check boundingBox before continuing
-
-			if ( geometry.boundingBox !== null ) {
-
-				if ( _ray$1.intersectsBox( geometry.boundingBox ) === false ) continue;
-
-			}
-
-			var intersection;
-
-			if ( geometry.isBufferGeometry ) {
-
-				var a, b, c;
-				var index = geometry.index;
-				var position = geometry.attributes.position;
-				var uv = geometry.attributes.uv;
-				var uv2 = geometry.attributes.uv2;
-				var groups = geometry.groups;
-				var drawRange = geometry.drawRange;
-				var i, j, il, jl;
-				var group, groupMaterial;
-				var start, end;
-
-				if ( index !== null ) {
-
-					// indexed buffer geometry
-
-					if ( Array.isArray( material ) ) {
-
-						for ( i = 0, il = groups.length; i < il; i ++ ) {
-
-							group = groups[ i ];
-							groupMaterial = material[ group.materialIndex ];
-
-							start = Math.max( group.start, drawRange.start );
-							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
-
-							for ( j = start, jl = end; j < jl; j += 3 ) {
-
-								a = index.getX( j );
-								b = index.getX( j + 1 );
-								c = index.getX( j + 2 );
-
-								intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, groupMaterial, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-								if ( intersection ) {
-
-									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
-									intersection.face.materialIndex = group.materialIndex;
-
-									intersection.instanceID = instanceID;
-
-									intersects.push( intersection );
-
-								}
-
-							}
-
-						}
-
-					} else {
-
-						start = Math.max( 0, drawRange.start );
-						end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
-
-						for ( i = start, il = end; i < il; i += 3 ) {
-
-							a = index.getX( i );
-							b = index.getX( i + 1 );
-							c = index.getX( i + 2 );
-
-							intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, material, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-							if ( intersection ) {
-
-								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
-
-								intersection.instanceID = instanceID;
-
-								intersects.push( intersection );
-
-							}
-
-						}
-
-					}
-
-				} else if ( position !== undefined ) {
-
-					// non-indexed buffer geometry
-
-					if ( Array.isArray( material ) ) {
-
-						for ( i = 0, il = groups.length; i < il; i ++ ) {
-
-							group = groups[ i ];
-							groupMaterial = material[ group.materialIndex ];
-
-							start = Math.max( group.start, drawRange.start );
-							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
-
-							for ( j = start, jl = end; j < jl; j += 3 ) {
-
-								a = j;
-								b = j + 1;
-								c = j + 2;
-
-								intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, groupMaterial, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-								if ( intersection ) {
-
-									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
-									intersection.face.materialIndex = group.materialIndex;
-
-									intersection.instanceID = instanceID;
-
-									intersects.push( intersection );
-
-								}
-
-							}
-
-						}
-
-					} else {
-
-						start = Math.max( 0, drawRange.start );
-						end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
-
-						for ( i = start, il = end; i < il; i += 3 ) {
-
-							a = i;
-							b = i + 1;
-							c = i + 2;
-
-							intersection = checkBufferGeometryIntersection$1( this, instanceMatrixWorld, material, raycaster, _ray$1, position, uv, uv2, a, b, c );
-
-							if ( intersection ) {
-
-								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
+	getMatrixAt: function ( index, matrix ) {
 
-								intersection.instanceID = instanceID;
-
-								intersects.push( intersection );
-
-							}
-
-						}
-
-					}
-
-				}
-
-			}
-
-
-
-
-		}
-
-	},
-
-	getMatrixAt: function ( index ) {
-
-		var matrix = new Matrix4();
+		var matrix = matrix || new Matrix4();
 
 		matrix.fromArray( this.instanceMatrix.array, index * 16 );
 
@@ -27529,84 +27345,12 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	},
 
-	updateMorphTargets: function () {
-
-	}
+	// updateMorphTargets: function () {
+    //
+	// }
 
 } );
 
-function checkIntersection$1( object, matrixWorld, material, raycaster, ray, pA, pB, pC, point ) {
-
-	var intersect;
-
-	if ( material.side === BackSide ) {
-
-		intersect = ray.intersectTriangle( pC, pB, pA, true, point );
-
-	} else {
-
-		intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
-
-	}
-
-	if ( intersect === null ) return null;
-
-	_intersectionPointWorld$1.copy( point );
-	_intersectionPointWorld$1.applyMatrix4( matrixWorld );
-
-	var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld$1 );
-
-	if ( distance < raycaster.near || distance > raycaster.far ) return null;
-
-	return {
-		distance: distance,
-		point: _intersectionPointWorld$1.clone(),
-		object: object
-	};
-
-}
-
-function checkBufferGeometryIntersection$1( object, matrixWorld, material, raycaster, ray, position, uv, uv2, a, b, c ) {
-
-	_vA$2.fromBufferAttribute( position, a );
-	_vB$2.fromBufferAttribute( position, b );
-	_vC$2.fromBufferAttribute( position, c );
-
-	var intersection = checkIntersection$1( object, matrixWorld, material, raycaster, ray, _vA$2, _vB$2, _vC$2, _intersectionPoint$1 );
-
-	if ( intersection ) {
-
-		if ( uv ) {
-
-			_uvA$2.fromBufferAttribute( uv, a );
-			_uvB$2.fromBufferAttribute( uv, b );
-			_uvC$2.fromBufferAttribute( uv, c );
-
-			intersection.uv = Triangle.getUV( _intersectionPoint$1, _vA$2, _vB$2, _vC$2, _uvA$2, _uvB$2, _uvC$2, new Vector2() );
-
-		}
-
-		if ( uv2 ) {
-
-			_uvA$2.fromBufferAttribute( uv2, a );
-			_uvB$2.fromBufferAttribute( uv2, b );
-			_uvC$2.fromBufferAttribute( uv2, c );
-
-			intersection.uv2 = Triangle.getUV( _intersectionPoint$1, _vA$2, _vB$2, _vC$2, _uvA$2, _uvB$2, _uvC$2, new Vector2() );
-
-		}
-
-		var face = new Face3( a, b, c );
-		Triangle.getNormal( _vA$2, _vB$2, _vC$2, face.normal );
-
-		intersection.face = face;
-
-	}
-
-	return intersection;
-
-}
-
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author alteredq / http://alteredqualia.com/
@@ -27662,9 +27406,9 @@ LineBasicMaterial.prototype.copy = function ( source ) {
 
 var _start = new Vector3();
 var _end = new Vector3();
-var _inverseMatrix$2 = new Matrix4();
-var _ray$2 = new Ray();
-var _sphere$3 = new Sphere();
+var _inverseMatrix$1 = new Matrix4();
+var _ray$1 = new Ray();
+var _sphere$2 = new Sphere();
 
 function Line( geometry, material, mode ) {
 
@@ -27751,16 +27495,16 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
 
-		_sphere$3.copy( geometry.boundingSphere );
-		_sphere$3.applyMatrix4( matrixWorld );
-		_sphere$3.radius += precision;
+		_sphere$2.copy( geometry.boundingSphere );
+		_sphere$2.applyMatrix4( matrixWorld );
+		_sphere$2.radius += precision;
 
-		if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;
+		if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) return;
 
 		//
 
-		_inverseMatrix$2.getInverse( matrixWorld );
-		_ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
+		_inverseMatrix$1.getInverse( matrixWorld );
+		_ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );
 
 		var localPrecision = precision / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
 		var localPrecisionSq = localPrecision * localPrecision;
@@ -27789,7 +27533,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 					vStart.fromArray( positions, a * 3 );
 					vEnd.fromArray( positions, b * 3 );
 
-					var distSq = _ray$2.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
+					var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
 
 					if ( distSq > localPrecisionSq ) continue;
 
@@ -27821,7 +27565,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 					vStart.fromArray( positions, 3 * i );
 					vEnd.fromArray( positions, 3 * i + 3 );
 
-					var distSq = _ray$2.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
+					var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
 
 					if ( distSq > localPrecisionSq ) continue;
 
@@ -27855,7 +27599,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 			for ( var i = 0; i < nbVertices - 1; i += step ) {
 
-				var distSq = _ray$2.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
+				var distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
 
 				if ( distSq > localPrecisionSq ) continue;
 
@@ -28053,9 +27797,9 @@ PointsMaterial.prototype.copy = function ( source ) {
  * @author alteredq / http://alteredqualia.com/
  */
 
-var _inverseMatrix$3 = new Matrix4();
-var _ray$3 = new Ray();
-var _sphere$4 = new Sphere();
+var _inverseMatrix$2 = new Matrix4();
+var _ray$2 = new Ray();
+var _sphere$3 = new Sphere();
 var _position$1 = new Vector3();
 
 function Points( geometry, material ) {
@@ -28087,16 +27831,16 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
 
-		_sphere$4.copy( geometry.boundingSphere );
-		_sphere$4.applyMatrix4( matrixWorld );
-		_sphere$4.radius += threshold;
+		_sphere$3.copy( geometry.boundingSphere );
+		_sphere$3.applyMatrix4( matrixWorld );
+		_sphere$3.radius += threshold;
 
-		if ( raycaster.ray.intersectsSphere( _sphere$4 ) === false ) return;
+		if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;
 
 		//
 
-		_inverseMatrix$3.getInverse( matrixWorld );
-		_ray$3.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$3 );
+		_inverseMatrix$2.getInverse( matrixWorld );
+		_ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
 
 		var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
 		var localThresholdSq = localThreshold * localThreshold;
@@ -28203,13 +27947,13 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
 
-	var rayPointDistanceSq = _ray$3.distanceSqToPoint( point );
+	var rayPointDistanceSq = _ray$2.distanceSqToPoint( point );
 
 	if ( rayPointDistanceSq < localThresholdSq ) {
 
 		var intersectPoint = new Vector3();
 
-		_ray$3.closestPointToPoint( point, intersectPoint );
+		_ray$2.closestPointToPoint( point, intersectPoint );
 		intersectPoint.applyMatrix4( matrixWorld );
 
 		var distance = raycaster.ray.origin.distanceTo( intersectPoint );

+ 1 - 0
examples/files.js

@@ -49,6 +49,7 @@ var files = {
 		"webgl_helpers",
 		"webgl_instancing_suzanne",
 		"webgl_instancing_raycast",
+		"webgl_instancing_morphtargets_raycast",
 		"webgl_interactive_buffergeometry",
 		"webgl_interactive_cubes",
 		"webgl_interactive_cubes_gpu",

+ 195 - 0
examples/webgl_instancing_morphtargets_raycast.html

@@ -0,0 +1,195 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<title>three.js webgl - instancing - morph targets - raycast </title>
+	<meta charset="utf-8">
+	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+	<link type="text/css" rel="stylesheet" href="main.css">
+</head>
+<body>
+<div id="container"></div>
+<div id="info">
+	<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - WebGL instancing morphTarget raycast
+	example
+</div>
+
+<script type="module">
+
+	import * as THREE from '../build/three.module.js';
+
+	import Stats from './jsm/libs/stats.module.js';
+	import {OrbitControls} from './jsm/controls/OrbitControls.js';
+
+	var container;
+
+	var camera, scene, renderer, raycaster, controls, stats;
+
+	var mesh, mouse = new THREE.Vector2();
+
+	var object = new THREE.Object3D();
+
+	var amount = parseInt( window.location.search.substr( 1 ) ) || 10;
+
+	var count = Math.pow( amount, 3 );
+
+	var rotationTheta = 0.1;
+	var rotationMatrix = new THREE.Matrix4().makeRotationY( rotationTheta );
+	var instanceMatrix = new THREE.Matrix4();
+	var matrix = new THREE.Matrix4();
+
+	init();
+	animate();
+
+	function init() {
+
+		container = document.getElementById( 'container' );
+
+		scene = new THREE.Scene();
+		scene.background = new THREE.Color( 0x000000 );
+
+		camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
+		camera.position.set( 25, 25, 25 );
+		camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );
+		scene.add( camera );
+
+		var light = new THREE.AmbientLight( 0xffffff );
+		scene.add( light );
+
+		var geometry = new THREE.BoxGeometry( 0.5, 0.5, 0.5 );
+		var material = new THREE.MeshNormalMaterial( { morphTargets: true } );
+
+		// construct 8 blend shapes
+
+		for ( var i = 0; i < 8; i ++ ) {
+
+			var vertices = [];
+
+			for ( var v = 0; v < geometry.vertices.length; v ++ ) {
+
+				vertices.push( geometry.vertices[ v ].clone() );
+
+				if ( v === i ) {
+
+					vertices[ vertices.length - 1 ].x *= 2;
+					vertices[ vertices.length - 1 ].y *= 2;
+					vertices[ vertices.length - 1 ].z *= 2;
+
+				}
+
+			}
+
+			geometry.morphTargets.push( { name: "target" + i, vertices: vertices } );
+
+		}
+
+		geometry = new THREE.BufferGeometry().fromGeometry( geometry );
+
+		mesh = new THREE.InstancedMesh( geometry, material, count );
+
+		mesh.position.set( 0, 0, 0 );
+
+		var i = 0;
+		var offset = amount / 2;
+
+		for ( var x = 0; x < amount; x ++ ) {
+
+			for ( var y = 0; y < amount; y ++ ) {
+
+				for ( var z = 0; z < amount; z ++ ) {
+
+					object.position.set( ( offset - x ) * 2, ( offset - y ) * 2, ( offset - z ) * 2 );
+
+					object.updateMatrix();
+
+					mesh.setMatrixAt( i ++, object.matrix );
+
+				}
+
+			}
+
+		}
+
+		scene.add( mesh );
+
+		raycaster = new THREE.Raycaster();
+
+		renderer = new THREE.WebGLRenderer( { antialias: true } );
+		renderer.setPixelRatio( window.devicePixelRatio );
+		renderer.setSize( window.innerWidth, window.innerHeight );
+		container.appendChild( renderer.domElement );
+
+		controls = new OrbitControls( camera, renderer.domElement );
+
+		stats = new Stats();
+		document.body.appendChild( stats.dom );
+
+		window.addEventListener( 'resize', onWindowResize, false );
+
+		document.addEventListener( 'mousemove', onMouseMove, false );
+
+	}
+
+	function onMouseMove( 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();
+
+	}
+
+	function updateMorphTargetInfluences() {
+
+		for ( var i = 0; i < mesh.morphTargetInfluences.length; i ++ ) {
+
+			mesh.morphTargetInfluences[ i ] = Math.sin( Date.now() * 0.001 ) + 0.5;
+
+		}
+
+	}
+
+	function render() {
+
+		updateMorphTargetInfluences();
+
+		raycaster.setFromCamera( mouse, camera );
+
+		var intersects = raycaster.intersectObject( mesh );
+
+		if ( intersects.length > 0 ) {
+
+			mesh.getMatrixAt( intersects[ 0 ].instanceId, instanceMatrix );
+			matrix.multiplyMatrices( instanceMatrix, rotationMatrix );
+
+			mesh.setMatrixAt( intersects[ 0 ].instanceId, matrix );
+			mesh.instanceMatrix.needsUpdate = true;
+
+		}
+
+		renderer.render( scene, camera );
+
+		stats.update();
+
+	}
+
+
+</script>
+
+</body>
+</html>

+ 44 - 41
examples/webgl_instancing_raycast.html

@@ -18,8 +18,8 @@
 	var camera, scene, renderer, stats;
 
 	var mesh, geometry;
-	var amount = parseInt(window.location.search.substr(1)) || 10;
-	var count = Math.pow(amount, 3);
+	var amount = parseInt( window.location.search.substr( 1 ) ) || 10;
+	var count = Math.pow( amount, 3 );
 	var object = new THREE.Object3D();
 
 	var intersection;
@@ -28,42 +28,45 @@
 
 	var orbitControls;
 
-	var rotationOffset=0.1;
+	var rotationTheta = 0.1;
+	var rotationMatrix = new THREE.Matrix4().makeRotationY( rotationTheta );
+	var instanceMatrix = new THREE.Matrix4();
+	var matrix = new THREE.Matrix4();
 
 	init();
 	animate();
 
 	function init() {
 
-		camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
-		camera.position.set(amount , amount , amount );
-		camera.lookAt(0, 0, 0);
+		camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
+		camera.position.set( amount, amount, amount );
+		camera.lookAt( 0, 0, 0 );
 
 
 		scene = new THREE.Scene();
 
-		geometry = new THREE.BoxBufferGeometry(1, 1, 1);
+		geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
 		geometry.computeVertexNormals();
-		geometry.scale(0.5, 0.5, 0.5);
+		geometry.scale( 0.5, 0.5, 0.5 );
 
 		var material = new THREE.MeshNormalMaterial();
 
-		mesh = new THREE.InstancedMesh(geometry, material, count);
+		mesh = new THREE.InstancedMesh( geometry, material, count );
 
 		var i = 0;
 		var offset = amount / 2;
 
-		for (var x = 0; x < amount; x++) {
+		for ( var x = 0; x < amount; x ++ ) {
 
-			for (var y = 0; y < amount; y++) {
+			for ( var y = 0; y < amount; y ++ ) {
 
-				for (var z = 0; z < amount; z++) {
+				for ( var z = 0; z < amount; z ++ ) {
 
-					object.position.set(offset - x, offset - y, offset - z);
+					object.position.set( offset - x, offset - y, offset - z );
 
 					object.updateMatrix();
 
-					mesh.setMatrixAt(i++, object.matrix);
+					mesh.setMatrixAt( i ++, object.matrix );
 
 				}
 
@@ -71,24 +74,24 @@
 
 		}
 
-		scene.add(mesh);
+		scene.add( mesh );
 
 
 		var gui = new GUI();
-		gui.add(mesh, 'count', 0, count);
+		gui.add( mesh, 'count', 0, count );
 
-		renderer = new THREE.WebGLRenderer({antialias: true});
-		renderer.setPixelRatio(window.devicePixelRatio);
-		renderer.setSize(window.innerWidth, window.innerHeight);
+		renderer = new THREE.WebGLRenderer( { antialias: true } );
+		renderer.setPixelRatio( window.devicePixelRatio );
+		renderer.setSize( window.innerWidth, window.innerHeight );
 
-		document.body.appendChild(renderer.domElement);
+		document.body.appendChild( renderer.domElement );
 
-		orbitControls=new OrbitControls(camera,renderer.domElement);
+		orbitControls = new OrbitControls( camera, renderer.domElement );
 
 		stats = new Stats();
-		document.body.appendChild(stats.dom);
+		document.body.appendChild( stats.dom );
 
-		window.addEventListener('resize', onWindowResize, false);
+		window.addEventListener( 'resize', onWindowResize, false );
 		document.addEventListener( 'mousemove', onMouseMove, false );
 
 	}
@@ -98,14 +101,22 @@
 		camera.aspect = window.innerWidth / window.innerHeight;
 		camera.updateProjectionMatrix();
 
-		renderer.setSize(window.innerWidth, window.innerHeight);
+		renderer.setSize( window.innerWidth, window.innerHeight );
 
 	}
 
+	function onMouseMove( event ) {
+
+		event.preventDefault();
+
+		mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
+		mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
+
+	}
 
 	function animate() {
 
-		requestAnimationFrame(animate);
+		requestAnimationFrame( animate );
 
 		render();
 
@@ -116,35 +127,27 @@
 
 		camera.updateMatrixWorld();
 
-		raycaster.setFromCamera(mouse, camera);
+		raycaster.setFromCamera( mouse, camera );
 
 		intersection = raycaster.intersectObjects( scene.children );
 
+		if ( intersection.length > 0 ) {
 
-		if (intersection.length > 0) {
+			mesh.getMatrixAt( intersection[ 0 ].instanceId, instanceMatrix );
+			matrix.multiplyMatrices( instanceMatrix, rotationMatrix );
 
-			var rotationMatrix=new THREE.Matrix4().makeRotationY(rotationOffset) ;
-			var instanceMatrix=mesh.getMatrixAt(intersection[0].instanceID);
-			var matrix=new THREE.Matrix4().multiplyMatrices(instanceMatrix,rotationMatrix);
-
-			mesh.setMatrixAt(intersection[0].instanceID,matrix);
+			mesh.setMatrixAt( intersection[ 0 ].instanceId, matrix );
 			mesh.instanceMatrix.needsUpdate = true;
+
 		}
 
-		renderer.render(scene, camera);
+		renderer.render( scene, camera );
 
 		stats.update();
-	}
-
-	function onMouseMove(event) {
-
-		event.preventDefault();
-
-		mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
-		mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 
 	}
 
+
 </script>
 
 </body>

+ 5 - 293
src/objects/InstancedMesh.js

@@ -3,29 +3,7 @@
  */
 import { BufferAttribute } from '../core/BufferAttribute.js';
 import { Mesh } from './Mesh.js';
-import { Vector3 } from '../math/Vector3.js';
-import { Vector2 } from '../math/Vector2.js';
-import { Sphere } from '../math/Sphere.js';
-import { Ray } from '../math/Ray.js';
 import { Matrix4 } from '../math/Matrix4.js';
-import { Triangle } from '../math/Triangle.js';
-import { Face3 } from '../core/Face3.js';
-import { DoubleSide, BackSide } from '../constants.js';
-
-var _inverseMatrix = new Matrix4();
-var _ray = new Ray();
-var _sphere = new Sphere();
-
-var _vA = new Vector3();
-var _vB = new Vector3();
-var _vC = new Vector3();
-
-var _uvA = new Vector2();
-var _uvB = new Vector2();
-var _uvC = new Vector2();
-
-var _intersectionPoint = new Vector3();
-var _intersectionPointWorld = new Vector3();
 
 function InstancedMesh( geometry, material, count ) {
 
@@ -43,203 +21,9 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	isInstancedMesh: true,
 
-	raycast: function ( raycaster, intersects ) {
-
-		var geometry = this.geometry;
-		var material = this.material;
-		var matrixWorld = this.matrixWorld;
-
-		if ( material === undefined ) return;
-
-		for ( var instanceID = 0; instanceID < this.count; instanceID ++ ) {
-
-			//Calculate the world matrix for each instance
-
-			var instanceMatrixWorld = new Matrix4();
-
-			var instanceMatrix = this.getMatrixAt( instanceID );
-
-			instanceMatrixWorld.multiplyMatrices( matrixWorld, instanceMatrix );
-
-			// Checking boundingSphere distance to ray
-
-			if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
-
-			_sphere.copy( geometry.boundingSphere );
-			_sphere.applyMatrix4( instanceMatrixWorld );
-
-			if ( raycaster.ray.intersectsSphere( _sphere ) === false ) continue;
-
-			//Transform the ray into the local space of the model
-
-			_inverseMatrix.getInverse( instanceMatrixWorld );
-			_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
-
-			// Check boundingBox before continuing
-
-			if ( geometry.boundingBox !== null ) {
-
-				if ( _ray.intersectsBox( geometry.boundingBox ) === false ) continue;
-
-			}
-
-			var intersection;
-
-			if ( geometry.isBufferGeometry ) {
-
-				var a, b, c;
-				var index = geometry.index;
-				var position = geometry.attributes.position;
-				var uv = geometry.attributes.uv;
-				var uv2 = geometry.attributes.uv2;
-				var groups = geometry.groups;
-				var drawRange = geometry.drawRange;
-				var i, j, il, jl;
-				var group, groupMaterial;
-				var start, end;
-
-				if ( index !== null ) {
-
-					// indexed buffer geometry
-
-					if ( Array.isArray( material ) ) {
-
-						for ( i = 0, il = groups.length; i < il; i ++ ) {
-
-							group = groups[ i ];
-							groupMaterial = material[ group.materialIndex ];
-
-							start = Math.max( group.start, drawRange.start );
-							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
-
-							for ( j = start, jl = end; j < jl; j += 3 ) {
-
-								a = index.getX( j );
-								b = index.getX( j + 1 );
-								c = index.getX( j + 2 );
-
-								intersection = checkBufferGeometryIntersection( this, instanceMatrixWorld, groupMaterial, raycaster, _ray, position, uv, uv2, a, b, c );
-
-								if ( intersection ) {
-
-									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
-									intersection.face.materialIndex = group.materialIndex;
-
-									intersection.instanceID = instanceID;
-
-									intersects.push( intersection );
-
-								}
-
-							}
-
-						}
-
-					} else {
-
-						start = Math.max( 0, drawRange.start );
-						end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
-
-						for ( i = start, il = end; i < il; i += 3 ) {
-
-							a = index.getX( i );
-							b = index.getX( i + 1 );
-							c = index.getX( i + 2 );
-
-							intersection = checkBufferGeometryIntersection( this, instanceMatrixWorld, material, raycaster, _ray, position, uv, uv2, a, b, c );
-
-							if ( intersection ) {
-
-								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
-
-								intersection.instanceID = instanceID;
-
-								intersects.push( intersection );
-
-							}
-
-						}
-
-					}
-
-				} else if ( position !== undefined ) {
-
-					// non-indexed buffer geometry
-
-					if ( Array.isArray( material ) ) {
-
-						for ( i = 0, il = groups.length; i < il; i ++ ) {
-
-							group = groups[ i ];
-							groupMaterial = material[ group.materialIndex ];
-
-							start = Math.max( group.start, drawRange.start );
-							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
-
-							for ( j = start, jl = end; j < jl; j += 3 ) {
-
-								a = j;
-								b = j + 1;
-								c = j + 2;
-
-								intersection = checkBufferGeometryIntersection( this, instanceMatrixWorld, groupMaterial, raycaster, _ray, position, uv, uv2, a, b, c );
+	getMatrixAt: function ( index, matrix ) {
 
-								if ( intersection ) {
-
-									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
-									intersection.face.materialIndex = group.materialIndex;
-
-									intersection.instanceID = instanceID;
-
-									intersects.push( intersection );
-
-								}
-
-							}
-
-						}
-
-					} else {
-
-						start = Math.max( 0, drawRange.start );
-						end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
-
-						for ( i = start, il = end; i < il; i += 3 ) {
-
-							a = i;
-							b = i + 1;
-							c = i + 2;
-
-							intersection = checkBufferGeometryIntersection( this, instanceMatrixWorld, material, raycaster, _ray, position, uv, uv2, a, b, c );
-
-							if ( intersection ) {
-
-								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
-
-								intersection.instanceID = instanceID;
-
-								intersects.push( intersection );
-
-							}
-
-						}
-
-					}
-
-				}
-
-			}
-
-
-
-
-		}
-
-	},
-
-	getMatrixAt: function ( index ) {
-
-		var matrix = new Matrix4();
+		var matrix = matrix || new Matrix4();
 
 		matrix.fromArray( this.instanceMatrix.array, index * 16 );
 
@@ -253,82 +37,10 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	},
 
-	updateMorphTargets: function () {
-
-	}
+	// updateMorphTargets: function () {
+    //
+	// }
 
 } );
 
-function checkIntersection( object, matrixWorld, material, raycaster, ray, pA, pB, pC, point ) {
-
-	var intersect;
-
-	if ( material.side === BackSide ) {
-
-		intersect = ray.intersectTriangle( pC, pB, pA, true, point );
-
-	} else {
-
-		intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
-
-	}
-
-	if ( intersect === null ) return null;
-
-	_intersectionPointWorld.copy( point );
-	_intersectionPointWorld.applyMatrix4( matrixWorld );
-
-	var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );
-
-	if ( distance < raycaster.near || distance > raycaster.far ) return null;
-
-	return {
-		distance: distance,
-		point: _intersectionPointWorld.clone(),
-		object: object
-	};
-
-}
-
-function checkBufferGeometryIntersection( object, matrixWorld, material, raycaster, ray, position, uv, uv2, a, b, c ) {
-
-	_vA.fromBufferAttribute( position, a );
-	_vB.fromBufferAttribute( position, b );
-	_vC.fromBufferAttribute( position, c );
-
-	var intersection = checkIntersection( object, matrixWorld, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint );
-
-	if ( intersection ) {
-
-		if ( uv ) {
-
-			_uvA.fromBufferAttribute( uv, a );
-			_uvB.fromBufferAttribute( uv, b );
-			_uvC.fromBufferAttribute( uv, c );
-
-			intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
-
-		}
-
-		if ( uv2 ) {
-
-			_uvA.fromBufferAttribute( uv2, a );
-			_uvB.fromBufferAttribute( uv2, b );
-			_uvC.fromBufferAttribute( uv2, c );
-
-			intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
-
-		}
-
-		var face = new Face3( a, b, c );
-		Triangle.getNormal( _vA, _vB, _vC, face.normal );
-
-		intersection.face = face;
-
-	}
-
-	return intersection;
-
-}
-
 export { InstancedMesh };

+ 158 - 133
src/objects/Mesh.js

@@ -21,6 +21,10 @@ var _inverseMatrix = new Matrix4();
 var _ray = new Ray();
 var _sphere = new Sphere();
 
+var _matrixWorld = new Matrix4();
+var _instanceMatrix = new Matrix4();
+var _executionTimes = 1;
+
 var _vA = new Vector3();
 var _vB = new Vector3();
 var _vC = new Vector3();
@@ -143,163 +147,194 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		if ( material === undefined ) return;
 
-		// Checking boundingSphere distance to ray
+		//Determine how many times raycast will execute
 
-		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
+		if ( this.isInstancedMesh ) {
 
-		_sphere.copy( geometry.boundingSphere );
-		_sphere.applyMatrix4( matrixWorld );
+			_executionTimes = this.count;
 
-		if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return;
+		} else {
 
-		//
+			_executionTimes = 1;
 
-		_inverseMatrix.getInverse( matrixWorld );
-		_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
+		}
 
-		// Check boundingBox before continuing
+		for ( var instanceId = 0; instanceId < _executionTimes; instanceId ++ ) {
 
-		if ( geometry.boundingBox !== null ) {
+			//Determine the world matrix for this calculation
 
-			if ( _ray.intersectsBox( geometry.boundingBox ) === false ) return;
+			if ( this.isInstancedMesh ) {
 
-		}
+				_instanceMatrix = this.getMatrixAt( instanceId );
+				_matrixWorld.multiplyMatrices( matrixWorld, _instanceMatrix );
 
-		// check unsupported draw modes
+			} else {
 
-		if ( this.drawMode !== TrianglesDrawMode ) {
+				_matrixWorld = matrixWorld;
 
-			console.warn( 'THREE.Mesh: TriangleStripDrawMode and TriangleFanDrawMode are not supported by .raycast().' );
-			return;
+			}
 
-		}
+			// Checking boundingSphere distance to ray
 
-		var intersection;
+			if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
 
-		if ( geometry.isBufferGeometry ) {
+			_sphere.copy( geometry.boundingSphere );
+			_sphere.applyMatrix4( _matrixWorld );
 
-			var a, b, c;
-			var index = geometry.index;
-			var position = geometry.attributes.position;
-			var morphPosition = geometry.morphAttributes.position;
-			var morphTargetsRelative = geometry.morphTargetsRelative;
-			var uv = geometry.attributes.uv;
-			var uv2 = geometry.attributes.uv2;
-			var groups = geometry.groups;
-			var drawRange = geometry.drawRange;
-			var i, j, il, jl;
-			var group, groupMaterial;
-			var start, end;
+			if ( raycaster.ray.intersectsSphere( _sphere ) === false ) continue;
 
-			if ( index !== null ) {
+			//Transform the ray into the local space of the model
 
-				// indexed buffer geometry
+			_inverseMatrix.getInverse( _matrixWorld );
+			_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
 
-				if ( Array.isArray( material ) ) {
+			// Check boundingBox before continuing
 
-					for ( i = 0, il = groups.length; i < il; i ++ ) {
+			if ( geometry.boundingBox !== null ) {
 
-						group = groups[ i ];
-						groupMaterial = material[ group.materialIndex ];
+				if ( _ray.intersectsBox( geometry.boundingBox ) === false ) continue;
 
-						start = Math.max( group.start, drawRange.start );
-						end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+			}
 
-						for ( j = start, jl = end; j < jl; j += 3 ) {
+			var intersection;
 
-							a = index.getX( j );
-							b = index.getX( j + 1 );
-							c = index.getX( j + 2 );
+			if ( geometry.isBufferGeometry ) {
 
-							intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+				var a, b, c;
+				var index = geometry.index;
+				var position = geometry.attributes.position;
+				var morphPosition = geometry.morphAttributes.position;
+				var uv = geometry.attributes.uv;
+				var uv2 = geometry.attributes.uv2;
+				var groups = geometry.groups;
+				var drawRange = geometry.drawRange;
+				var i, j, il, jl;
+				var group, groupMaterial;
+				var start, end;
 
-							if ( intersection ) {
+				if ( index !== null ) {
 
-								intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
-								intersection.face.materialIndex = group.materialIndex;
-								intersects.push( intersection );
+					// indexed buffer geometry
+
+					if ( Array.isArray( material ) ) {
+
+						for ( i = 0, il = groups.length; i < il; i ++ ) {
+
+							group = groups[ i ];
+							groupMaterial = material[ group.materialIndex ];
+
+							start = Math.max( group.start, drawRange.start );
+							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+
+							for ( j = start, jl = end; j < jl; j += 3 ) {
+
+								a = index.getX( j );
+								b = index.getX( j + 1 );
+								c = index.getX( j + 2 );
+
+								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
+
+								if ( intersection ) {
+
+									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
+									intersection.face.materialIndex = group.materialIndex;
+
+									intersection.instanceId = instanceId;
+
+									intersects.push( intersection );
+
+								}
 
 							}
 
 						}
 
-					}
+					} else {
+
+						start = Math.max( 0, drawRange.start );
+						end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
 
-				} else {
+						for ( i = start, il = end; i < il; i += 3 ) {
 
-					start = Math.max( 0, drawRange.start );
-					end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
+							a = index.getX( i );
+							b = index.getX( i + 1 );
+							c = index.getX( i + 2 );
 
-					for ( i = start, il = end; i < il; i += 3 ) {
+							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
 
-						a = index.getX( i );
-						b = index.getX( i + 1 );
-						c = index.getX( i + 2 );
+							if ( intersection ) {
+
+								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
 
-						intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+								intersection.instanceId = instanceId;
 
-						if ( intersection ) {
+								intersects.push( intersection );
 
-							intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics
-							intersects.push( intersection );
+							}
 
 						}
 
 					}
 
-				}
+				} else if ( position !== undefined ) {
 
-			} else if ( position !== undefined ) {
+					// non-indexed buffer geometry
 
-				// non-indexed buffer geometry
+					if ( Array.isArray( material ) ) {
 
-				if ( Array.isArray( material ) ) {
+						for ( i = 0, il = groups.length; i < il; i ++ ) {
 
-					for ( i = 0, il = groups.length; i < il; i ++ ) {
+							group = groups[ i ];
+							groupMaterial = material[ group.materialIndex ];
 
-						group = groups[ i ];
-						groupMaterial = material[ group.materialIndex ];
+							start = Math.max( group.start, drawRange.start );
+							end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
 
-						start = Math.max( group.start, drawRange.start );
-						end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
+							for ( j = start, jl = end; j < jl; j += 3 ) {
 
-						for ( j = start, jl = end; j < jl; j += 3 ) {
+								a = j;
+								b = j + 1;
+								c = j + 2;
 
-							a = j;
-							b = j + 1;
-							c = j + 2;
+								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
 
-							intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+								if ( intersection ) {
 
-							if ( intersection ) {
+									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
+									intersection.face.materialIndex = group.materialIndex;
 
-								intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
-								intersection.face.materialIndex = group.materialIndex;
-								intersects.push( intersection );
+									intersection.instanceId = instanceId;
+
+									intersects.push( intersection );
+
+								}
 
 							}
 
 						}
 
-					}
+					} else {
 
-				} else {
+						start = Math.max( 0, drawRange.start );
+						end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
 
-					start = Math.max( 0, drawRange.start );
-					end = Math.min( position.count, ( drawRange.start + drawRange.count ) );
+						for ( i = start, il = end; i < il; i += 3 ) {
 
-					for ( i = start, il = end; i < il; i += 3 ) {
+							a = i;
+							b = i + 1;
+							c = i + 2;
 
-						a = i;
-						b = i + 1;
-						c = i + 2;
+							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c );
 
-						intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
+							if ( intersection ) {
+
+								intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
 
-						if ( intersection ) {
+								intersection.instanceId = instanceId;
 
-							intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics
-							intersects.push( intersection );
+								intersects.push( intersection );
+
+							}
 
 						}
 
@@ -307,49 +342,49 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 				}
 
-			}
+			} else if ( geometry.isGeometry ) {
 
-		} else if ( geometry.isGeometry ) {
+				var fvA, fvB, fvC;
+				var isMultiMaterial = Array.isArray( material );
 
-			var fvA, fvB, fvC;
-			var isMultiMaterial = Array.isArray( material );
+				var vertices = geometry.vertices;
+				var faces = geometry.faces;
+				var uvs;
 
-			var vertices = geometry.vertices;
-			var faces = geometry.faces;
-			var uvs;
+				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
+				if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
 
-			var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
-			if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
+				for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
 
-			for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
+					var face = faces[ f ];
+					var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
 
-				var face = faces[ f ];
-				var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
+					if ( faceMaterial === undefined ) continue;
 
-				if ( faceMaterial === undefined ) continue;
+					fvA = vertices[ face.a ];
+					fvB = vertices[ face.b ];
+					fvC = vertices[ face.c ];
 
-				fvA = vertices[ face.a ];
-				fvB = vertices[ face.b ];
-				fvC = vertices[ face.c ];
+					intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
 
-				intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
+					if ( intersection ) {
 
-				if ( intersection ) {
+						if ( uvs && uvs[ f ] ) {
 
-					if ( uvs && uvs[ f ] ) {
+							var uvs_f = uvs[ f ];
+							_uvA.copy( uvs_f[ 0 ] );
+							_uvB.copy( uvs_f[ 1 ] );
+							_uvC.copy( uvs_f[ 2 ] );
 
-						var uvs_f = uvs[ f ];
-						_uvA.copy( uvs_f[ 0 ] );
-						_uvB.copy( uvs_f[ 1 ] );
-						_uvC.copy( uvs_f[ 2 ] );
+							intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
 
-						intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
+						}
 
-					}
+						intersection.face = face;
+						intersection.faceIndex = f;
+						intersects.push( intersection );
 
-					intersection.face = face;
-					intersection.faceIndex = f;
-					intersects.push( intersection );
+					}
 
 				}
 
@@ -384,7 +419,7 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point
 	if ( intersect === null ) return null;
 
 	_intersectionPointWorld.copy( point );
-	_intersectionPointWorld.applyMatrix4( object.matrixWorld );
+	_intersectionPointWorld.applyMatrix4( _matrixWorld );
 
 	var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );
 
@@ -398,7 +433,7 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point
 
 }
 
-function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {
+function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) {
 
 	_vA.fromBufferAttribute( position, a );
 	_vB.fromBufferAttribute( position, b );
@@ -423,19 +458,9 @@ function checkBufferGeometryIntersection( object, material, raycaster, ray, posi
 			_tempB.fromBufferAttribute( morphAttribute, b );
 			_tempC.fromBufferAttribute( morphAttribute, c );
 
-			if ( morphTargetsRelative ) {
-
-				_morphA.addScaledVector( _tempA, influence );
-				_morphB.addScaledVector( _tempB, influence );
-				_morphC.addScaledVector( _tempC, influence );
-
-			} else {
-
-				_morphA.addScaledVector( _tempA.sub( _vA ), influence );
-				_morphB.addScaledVector( _tempB.sub( _vB ), influence );
-				_morphC.addScaledVector( _tempC.sub( _vC ), influence );
-
-			}
+			_morphA.addScaledVector( _tempA.sub( _vA ), influence );
+			_morphB.addScaledVector( _tempB.sub( _vB ), influence );
+			_morphC.addScaledVector( _tempC.sub( _vC ), influence );
 
 		}