فهرست منبع

Cleaned up Raycaster BufferGeometry implementation.
There are many allocations that would still need to be removed though.

Mr.doob 12 سال پیش
والد
کامیت
916952b774
1فایلهای تغییر یافته به همراه128 افزوده شده و 144 حذف شده
  1. 128 144
      src/core/Raycaster.js

+ 128 - 144
src/core/Raycaster.js

@@ -64,224 +64,208 @@
 
 			intersectObject( object.getObjectForDistance( distance ), raycaster, intersects );
 
-		} else if (object instanceof THREE.Mesh && object.geometry instanceof THREE.BufferGeometry) {
+		} else if (object instanceof THREE.Mesh ) {
 
 			// Checking boundingSphere distance to ray
-			matrixPosition.getPositionFromMatrix(object.matrixWorld);
-			sphere.set(matrixPosition,
-				object.geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis());
+			matrixPosition.getPositionFromMatrix( object.matrixWorld );
+			sphere.set( matrixPosition, object.geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis() );
 
-			if (!raycaster.ray.isIntersectionSphere(sphere)) {
+			if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
 
 				return intersects;
 
 			}
 
-			// Checking faces
-
 			var geometry = object.geometry;
 			var vertices = geometry.vertices;
 
-			var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
-			var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
+			if ( geometry instanceof THREE.BufferGeometry ) {
 
-			var side = object.material.side;
+				var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
+				var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
 
-			var a, b, c;
-			var precision = raycaster.precision;
+				var side = object.material.side;
 
-			inverseMatrix.getInverse(object.matrixWorld);
+				var a, b, c;
+				var precision = raycaster.precision;
 
-			localRay.copy(raycaster.ray).applyMatrix4(inverseMatrix);
+				inverseMatrix.getInverse(object.matrixWorld);
 
-			if (!geometry.dynamic) return intersects;
+				localRay.copy(raycaster.ray).applyMatrix4(inverseMatrix);
 
-			var fl;
-			var indexed = false;
-			if (geometry.attributes.index) {
-				indexed = true;
-				fl = geometry.attributes.index.numItems / 3;
-			} else {
-				fl = geometry.attributes.position.numItems / 9;
-			}
+				if (!geometry.dynamic) return intersects;
 
-			for (var f = 0; f < fl; f++) {
-
-				if (indexed) {
-					a = geometry.attributes.index.array[f * 3];
-					b = geometry.attributes.index.array[f * 3 + 1];
-					c = geometry.attributes.index.array[f * 3 + 2];
+				var fl;
+				var indexed = false;
+				if (geometry.attributes.index) {
+					indexed = true;
+					fl = geometry.attributes.index.numItems / 3;
 				} else {
-					a = f * 3;
-					b = f * 3 + 1;
-					c = f * 3 + 2;
+					fl = geometry.attributes.position.numItems / 9;
 				}
 
-				var v1 = [geometry.attributes.position.array[a * 3],
-							geometry.attributes.position.array[a * 3 + 1],
-							geometry.attributes.position.array[a * 3 + 2]];
-				var v2 = [geometry.attributes.position.array[b * 3],
-							geometry.attributes.position.array[b * 3 + 1],
-							geometry.attributes.position.array[b * 3 + 2]];
-				var v3 = [geometry.attributes.position.array[c * 3],
-							geometry.attributes.position.array[c * 3 + 1],
-							geometry.attributes.position.array[c * 3 + 2]];
+				for (var f = 0; f < fl; f++) {
 
-				var material = object.material;
-				if (material === undefined) continue;
+					if (indexed) {
+						a = geometry.attributes.index.array[f * 3];
+						b = geometry.attributes.index.array[f * 3 + 1];
+						c = geometry.attributes.index.array[f * 3 + 2];
+					} else {
+						a = f * 3;
+						b = f * 3 + 1;
+						c = f * 3 + 2;
+					}
 
-				var cb = new THREE.Vector3(), ab = new THREE.Vector3();
-				var vA = new THREE.Vector3(v1[0], v1[1], v1[2]);
-				var vB = new THREE.Vector3(v2[0], v2[1], v2[2]);
-				var vC = new THREE.Vector3(v3[0], v3[1], v3[2]);
+					var v1 = [geometry.attributes.position.array[a * 3],
+								geometry.attributes.position.array[a * 3 + 1],
+								geometry.attributes.position.array[a * 3 + 2]];
+					var v2 = [geometry.attributes.position.array[b * 3],
+								geometry.attributes.position.array[b * 3 + 1],
+								geometry.attributes.position.array[b * 3 + 2]];
+					var v3 = [geometry.attributes.position.array[c * 3],
+								geometry.attributes.position.array[c * 3 + 1],
+								geometry.attributes.position.array[c * 3 + 2]];
 
-				cb.subVectors(vC, vB);
-				ab.subVectors(vA, vB);
-				cb.cross(ab);
-				cb.normalize();
+					var material = object.material;
+					if (material === undefined) continue;
 
-				facePlane.setFromNormalAndCoplanarPoint(cb, vA);
+					var cb = new THREE.Vector3(), ab = new THREE.Vector3();
+					var vA = new THREE.Vector3(v1[0], v1[1], v1[2]);
+					var vB = new THREE.Vector3(v2[0], v2[1], v2[2]);
+					var vC = new THREE.Vector3(v3[0], v3[1], v3[2]);
 
-				var planeDistance = localRay.distanceToPlane(facePlane);
+					cb.subVectors(vC, vB);
+					ab.subVectors(vA, vB);
+					cb.cross(ab);
+					cb.normalize();
 
-				// bail if raycaster and plane are parallel
-				if (Math.abs(planeDistance) < precision) continue;
+					facePlane.setFromNormalAndCoplanarPoint(cb, vA);
 
-				// if negative distance, then plane is behind raycaster
-				if (planeDistance < 0) continue;
+					var planeDistance = localRay.distanceToPlane(facePlane);
 
-				// check if we hit the wrong side of a single sided face
-				side = material.side;
-				if (side !== THREE.DoubleSide) {
+					// bail if raycaster and plane are parallel
+					if (Math.abs(planeDistance) < precision) continue;
 
-					var planeSign = localRay.direction.dot(facePlane.normal);
+					// if negative distance, then plane is behind raycaster
+					if (planeDistance < 0) continue;
 
-					if (!(side === THREE.FrontSide ? planeSign < 0 : planeSign > 0)) continue;
+					// check if we hit the wrong side of a single sided face
+					side = material.side;
+					if (side !== THREE.DoubleSide) {
 
-				}
+						var planeSign = localRay.direction.dot(facePlane.normal);
 
-				// this can be done using the planeDistance from localRay because localRay wasn't normalized, but ray was
-				if (planeDistance < raycaster.near || planeDistance > raycaster.far) continue;
+						if (!(side === THREE.FrontSide ? planeSign < 0 : planeSign > 0)) continue;
 
-				intersectPoint = localRay.at(planeDistance, intersectPoint); // passing in intersectPoint avoids a copy
+					}
 
-				if (!THREE.Triangle.containsPoint(intersectPoint, vA, vB, vC)) continue;
+					// this can be done using the planeDistance from localRay because localRay wasn't normalized, but ray was
+					if (planeDistance < raycaster.near || planeDistance > raycaster.far) continue;
 
-				var face = new THREE.Face3(a, b, c);
-				var colors = geometry.attributes.color.array;
-				face.vertexColors[0] = new THREE.Color(colors[a * 3], colors[a * 3 + 1], colors[a * 3 + 2]);
-				face.vertexColors[1] = new THREE.Color(colors[b * 3], colors[b * 3 + 1], colors[b * 3 + 2]);
-				face.vertexColors[2] = new THREE.Color(colors[c * 3], colors[c * 3 + 1], colors[c * 3 + 2]);
-				intersects.push({
-					distance: planeDistance, // this works because the original ray was normalized, and the transformed localRay wasn't
-					point: raycaster.ray.at(planeDistance),
-					face: face,
-					faceIndex: f,
-					object: object
-				});
+					intersectPoint = localRay.at(planeDistance, intersectPoint); // passing in intersectPoint avoids a copy
 
-			}
+					if (!THREE.Triangle.containsPoint(intersectPoint, vA, vB, vC)) continue;
 
-		} else if ( object instanceof THREE.Mesh ) {
+					var face = new THREE.Face3(a, b, c);
+					var colors = geometry.attributes.color.array;
+					face.vertexColors[0] = new THREE.Color(colors[a * 3], colors[a * 3 + 1], colors[a * 3 + 2]);
+					face.vertexColors[1] = new THREE.Color(colors[b * 3], colors[b * 3 + 1], colors[b * 3 + 2]);
+					face.vertexColors[2] = new THREE.Color(colors[c * 3], colors[c * 3 + 1], colors[c * 3 + 2]);
+					intersects.push({
+						distance: planeDistance, // this works because the original ray was normalized, and the transformed localRay wasn't
+						point: raycaster.ray.at(planeDistance),
+						face: face,
+						faceIndex: f,
+						object: object
+					});
 
-			// Checking boundingSphere distance to ray
-			matrixPosition.getPositionFromMatrix( object.matrixWorld );
-			sphere.set(
-				matrixPosition,
-				object.geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis() );
+				}
 
-			if ( ! raycaster.ray.isIntersectionSphere( sphere ) ) {
+			} else if ( geometry instanceof THREE.Geometry ) {
 
-				return intersects;
+				var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
+				var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
 
-			}
+				var side = object.material.side;
 
-			// Checking faces
+				var a, b, c, d;
+				var precision = raycaster.precision;
 
-			var geometry = object.geometry;
-			var vertices = geometry.vertices;
+				inverseMatrix.getInverse( object.matrixWorld );
 
-			var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
-			var objectMaterials = isFaceMaterial === true ? object.material.materials : null;
+				localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
 
-			var side = object.material.side;
+				for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
 
-			var a, b, c, d;
-			var precision = raycaster.precision;
+					var face = geometry.faces[ f ];
 
-			inverseMatrix.getInverse( object.matrixWorld );
+					var material = isFaceMaterial === true ? objectMaterials[ face.materialIndex ] : object.material;
 
-			localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
+					if ( material === undefined ) continue;
 
-			for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
+					facePlane.setFromNormalAndCoplanarPoint( face.normal, vertices[face.a] );
 
-				var face = geometry.faces[ f ];
+					var planeDistance = localRay.distanceToPlane( facePlane );
 
-				var material = isFaceMaterial === true ? objectMaterials[ face.materialIndex ] : object.material;
+					// bail if raycaster and plane are parallel
+					if ( Math.abs( planeDistance ) < precision ) continue;
 
-				if ( material === undefined ) continue;
+					// if negative distance, then plane is behind raycaster
+					if ( planeDistance < 0 ) continue;
 
-				facePlane.setFromNormalAndCoplanarPoint( face.normal, vertices[face.a] );
+					// check if we hit the wrong side of a single sided face
+					side = material.side;
+					if ( side !== THREE.DoubleSide ) {
 
-				var planeDistance = localRay.distanceToPlane( facePlane );
+						var planeSign = localRay.direction.dot( facePlane.normal );
 
-				// bail if raycaster and plane are parallel
-				if ( Math.abs( planeDistance ) < precision ) continue;
+						if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) continue;
 
-				// if negative distance, then plane is behind raycaster
-				if ( planeDistance < 0 ) continue;
+					}
 
-				// check if we hit the wrong side of a single sided face
-				side = material.side;
-				if ( side !== THREE.DoubleSide ) {
+					// this can be done using the planeDistance from localRay because localRay wasn't normalized, but ray was
+					if ( planeDistance < raycaster.near || planeDistance > raycaster.far ) continue;
 
-					var planeSign = localRay.direction.dot( facePlane.normal );
+					intersectPoint = localRay.at( planeDistance, intersectPoint ); // passing in intersectPoint avoids a copy
 
-					if ( ! ( side === THREE.FrontSide ? planeSign < 0 : planeSign > 0 ) ) continue;
+					if ( face instanceof THREE.Face3 ) {
 
-				}
+						a = vertices[ face.a ];
+						b = vertices[ face.b ];
+						c = vertices[ face.c ];
 
-				// this can be done using the planeDistance from localRay because localRay wasn't normalized, but ray was
-				if ( planeDistance < raycaster.near || planeDistance > raycaster.far ) continue;
+						if ( ! THREE.Triangle.containsPoint( intersectPoint, a, b, c ) ) continue;
 
-				intersectPoint = localRay.at( planeDistance, intersectPoint ); // passing in intersectPoint avoids a copy
+					} else if ( face instanceof THREE.Face4 ) {
 
-				if ( face instanceof THREE.Face3 ) {
+						a = vertices[ face.a ];
+						b = vertices[ face.b ];
+						c = vertices[ face.c ];
+						d = vertices[ face.d ];
 
-					a = vertices[ face.a ];
-					b = vertices[ face.b ];
-					c = vertices[ face.c ];
+						if ( ( ! THREE.Triangle.containsPoint( intersectPoint, a, b, d ) ) &&
+							 ( ! THREE.Triangle.containsPoint( intersectPoint, b, c, d ) ) ) continue;
 
-					if ( ! THREE.Triangle.containsPoint( intersectPoint, a, b, c ) ) continue;
+					} else {
 
-				} else if ( face instanceof THREE.Face4 ) {
+						// This is added because if we call out of this if/else group when none of the cases
+						//    match it will add a point to the intersection list erroneously.
+						throw Error( "face type not supported" );
 
-					a = vertices[ face.a ];
-					b = vertices[ face.b ];
-					c = vertices[ face.c ];
-					d = vertices[ face.d ];
+					}
 
-					if ( ( ! THREE.Triangle.containsPoint( intersectPoint, a, b, d ) ) &&
-						 ( ! THREE.Triangle.containsPoint( intersectPoint, b, c, d ) ) ) continue;
+					intersects.push( {
 
-				} else {
+						distance: planeDistance,	// this works because the original ray was normalized, and the transformed localRay wasn't
+						point: raycaster.ray.at( planeDistance ),
+						face: face,
+						faceIndex: f,
+						object: object
 
-					// This is added because if we call out of this if/else group when none of the cases
-					//    match it will add a point to the intersection list erroneously.
-					throw Error( "face type not supported" );
+					} );
 
 				}
 
-				intersects.push( {
-
-					distance: planeDistance,	// this works because the original ray was normalized, and the transformed localRay wasn't
-					point: raycaster.ray.at( planeDistance ),
-					face: face,
-					faceIndex: f,
-					object: object
-
-				} );
-
 			}
 
 		}