Pārlūkot izejas kodu

SelectionBox: Add support for OrthographicCamera.

Mugen87 5 gadi atpakaļ
vecāks
revīzija
80ff2d0f73

+ 94 - 42
examples/js/interactive/SelectionBox.js

@@ -16,6 +16,11 @@ THREE.SelectionBox = ( function () {
 	var vecDownRight = new THREE.Vector3();
 	var vecDownLeft = new THREE.Vector3();
 
+	var vecFarTopLeft = new THREE.Vector3();
+	var vecFarTopRight = new THREE.Vector3();
+	var vecFarDownRight = new THREE.Vector3();
+	var vecFarDownLeft = new THREE.Vector3();
+
 	var vectemp1 = new THREE.Vector3();
 	var vectemp2 = new THREE.Vector3();
 	var vectemp3 = new THREE.Vector3();
@@ -52,56 +57,103 @@ THREE.SelectionBox = ( function () {
 		this.camera.updateProjectionMatrix();
 		this.camera.updateMatrixWorld();
 
-		tmpPoint.copy( startPoint );
-		tmpPoint.x = Math.min( startPoint.x, endPoint.x );
-		tmpPoint.y = Math.max( startPoint.y, endPoint.y );
-		endPoint.x = Math.max( startPoint.x, endPoint.x );
-		endPoint.y = Math.min( startPoint.y, endPoint.y );
-
-		vecNear.copy( this.camera.position );
-		vecTopLeft.copy( tmpPoint );
-		vecTopRight.set( endPoint.x, tmpPoint.y, 0 );
-		vecDownRight.copy( endPoint );
-		vecDownLeft.set( tmpPoint.x, endPoint.y, 0 );
-
-		vecTopLeft.unproject( this.camera );
-		vecTopRight.unproject( this.camera );
-		vecDownRight.unproject( this.camera );
-		vecDownLeft.unproject( this.camera );
-
-		vectemp1.copy( vecTopLeft ).sub( vecNear );
-		vectemp2.copy( vecTopRight ).sub( vecNear );
-		vectemp3.copy( vecDownRight ).sub( vecNear );
-		vectemp1.normalize();
-		vectemp2.normalize();
-		vectemp3.normalize();
-
-		vectemp1.multiplyScalar( this.deep );
-		vectemp2.multiplyScalar( this.deep );
-		vectemp3.multiplyScalar( this.deep );
-		vectemp1.add( vecNear );
-		vectemp2.add( vecNear );
-		vectemp3.add( vecNear );
-
-		var planes = frustum.planes;
-
-		planes[ 0 ].setFromCoplanarPoints( vecNear, vecTopLeft, vecTopRight );
-		planes[ 1 ].setFromCoplanarPoints( vecNear, vecTopRight, vecDownRight );
-		planes[ 2 ].setFromCoplanarPoints( vecDownRight, vecDownLeft, vecNear );
-		planes[ 3 ].setFromCoplanarPoints( vecDownLeft, vecTopLeft, vecNear );
-		planes[ 4 ].setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
-		planes[ 5 ].setFromCoplanarPoints( vectemp3, vectemp2, vectemp1 );
-		planes[ 5 ].normal.multiplyScalar( - 1 );
+		if ( this.camera.isPerspectiveCamera ) {
+
+			tmpPoint.copy( startPoint );
+			tmpPoint.x = Math.min( startPoint.x, endPoint.x );
+			tmpPoint.y = Math.max( startPoint.y, endPoint.y );
+			endPoint.x = Math.max( startPoint.x, endPoint.x );
+			endPoint.y = Math.min( startPoint.y, endPoint.y );
+
+			vecNear.copy( this.camera.position );
+			vecTopLeft.copy( tmpPoint );
+			vecTopRight.set( endPoint.x, tmpPoint.y, 0 );
+			vecDownRight.copy( endPoint );
+			vecDownLeft.set( tmpPoint.x, endPoint.y, 0 );
+
+			vecTopLeft.unproject( this.camera );
+			vecTopRight.unproject( this.camera );
+			vecDownRight.unproject( this.camera );
+			vecDownLeft.unproject( this.camera );
+
+			vectemp1.copy( vecTopLeft ).sub( vecNear );
+			vectemp2.copy( vecTopRight ).sub( vecNear );
+			vectemp3.copy( vecDownRight ).sub( vecNear );
+			vectemp1.normalize();
+			vectemp2.normalize();
+			vectemp3.normalize();
+
+			vectemp1.multiplyScalar( this.deep );
+			vectemp2.multiplyScalar( this.deep );
+			vectemp3.multiplyScalar( this.deep );
+			vectemp1.add( vecNear );
+			vectemp2.add( vecNear );
+			vectemp3.add( vecNear );
+
+			var planes = frustum.planes;
+
+			planes[ 0 ].setFromCoplanarPoints( vecNear, vecTopLeft, vecTopRight );
+			planes[ 1 ].setFromCoplanarPoints( vecNear, vecTopRight, vecDownRight );
+			planes[ 2 ].setFromCoplanarPoints( vecDownRight, vecDownLeft, vecNear );
+			planes[ 3 ].setFromCoplanarPoints( vecDownLeft, vecTopLeft, vecNear );
+			planes[ 4 ].setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
+			planes[ 5 ].setFromCoplanarPoints( vectemp3, vectemp2, vectemp1 );
+			planes[ 5 ].normal.multiplyScalar( - 1 );
+
+		} else if ( this.camera.isOrthographicCamera ) {
+
+			if ( startPoint.equals( endPoint ) ) endPoint.addScalar( Number.EPSILON ); // avoid invalid frustum
+
+			var left = Math.min( startPoint.x, endPoint.x );
+			var top = Math.max( startPoint.y, endPoint.y );
+			var right = Math.max( startPoint.x, endPoint.x );
+			var down = Math.min( startPoint.y, endPoint.y );
+
+			vecTopLeft.set( left, top, - 1 );
+			vecTopRight.set( right, top, - 1 );
+			vecDownRight.set( right, down, - 1 );
+			vecDownLeft.set( left, down, - 1 );
+
+			vecFarTopLeft.set( left, top, 1 );
+			vecFarTopRight.set( right, top, 1 );
+			vecFarDownRight.set( right, down, 1 );
+			vecFarDownLeft.set( left, down, 1 );
+
+			vecTopLeft.unproject( this.camera );
+			vecTopRight.unproject( this.camera );
+			vecDownRight.unproject( this.camera );
+			vecDownLeft.unproject( this.camera );
+
+			vecFarTopLeft.unproject( this.camera );
+			vecFarTopRight.unproject( this.camera );
+			vecFarDownRight.unproject( this.camera );
+			vecFarDownLeft.unproject( this.camera );
+
+			var planes = frustum.planes;
+
+			planes[ 0 ].setFromCoplanarPoints( vecTopLeft, vecFarTopLeft, vecFarTopRight );
+			planes[ 1 ].setFromCoplanarPoints( vecTopRight, vecFarTopRight, vecFarDownRight );
+			planes[ 2 ].setFromCoplanarPoints( vecFarDownRight, vecFarDownLeft, vecDownLeft );
+			planes[ 3 ].setFromCoplanarPoints( vecFarDownLeft, vecFarTopLeft, vecTopLeft );
+			planes[ 4 ].setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
+			planes[ 5 ].setFromCoplanarPoints( vecFarDownRight, vecFarTopRight, vecFarTopLeft );
+			planes[ 5 ].normal.multiplyScalar( - 1 );
+
+		} else {
+
+			console.error( 'THREE.SelectionBox: Unsupported camera type.' );
+
+		}
 
 	};
 
 	SelectionBox.prototype.searchChildInFrustum = function ( frustum, object ) {
 
-		if ( object.isMesh ) {
+		if ( object.isMesh || object.isLine || object.isPoints ) {
 
 			if ( object.material !== undefined ) {
 
-				object.geometry.computeBoundingSphere();
+				if ( object.geometry.boundingSphere === null ) object.geometry.computeBoundingSphere();
 
 				center.copy( object.geometry.boundingSphere.center );
 

+ 94 - 42
examples/jsm/interactive/SelectionBox.js

@@ -21,6 +21,11 @@ var SelectionBox = ( function () {
 	var vecDownRight = new Vector3();
 	var vecDownLeft = new Vector3();
 
+	var vecFarTopLeft = new Vector3();
+	var vecFarTopRight = new Vector3();
+	var vecFarDownRight = new Vector3();
+	var vecFarDownLeft = new Vector3();
+
 	var vectemp1 = new Vector3();
 	var vectemp2 = new Vector3();
 	var vectemp3 = new Vector3();
@@ -57,56 +62,103 @@ var SelectionBox = ( function () {
 		this.camera.updateProjectionMatrix();
 		this.camera.updateMatrixWorld();
 
-		tmpPoint.copy( startPoint );
-		tmpPoint.x = Math.min( startPoint.x, endPoint.x );
-		tmpPoint.y = Math.max( startPoint.y, endPoint.y );
-		endPoint.x = Math.max( startPoint.x, endPoint.x );
-		endPoint.y = Math.min( startPoint.y, endPoint.y );
-
-		vecNear.copy( this.camera.position );
-		vecTopLeft.copy( tmpPoint );
-		vecTopRight.set( endPoint.x, tmpPoint.y, 0 );
-		vecDownRight.copy( endPoint );
-		vecDownLeft.set( tmpPoint.x, endPoint.y, 0 );
-
-		vecTopLeft.unproject( this.camera );
-		vecTopRight.unproject( this.camera );
-		vecDownRight.unproject( this.camera );
-		vecDownLeft.unproject( this.camera );
-
-		vectemp1.copy( vecTopLeft ).sub( vecNear );
-		vectemp2.copy( vecTopRight ).sub( vecNear );
-		vectemp3.copy( vecDownRight ).sub( vecNear );
-		vectemp1.normalize();
-		vectemp2.normalize();
-		vectemp3.normalize();
-
-		vectemp1.multiplyScalar( this.deep );
-		vectemp2.multiplyScalar( this.deep );
-		vectemp3.multiplyScalar( this.deep );
-		vectemp1.add( vecNear );
-		vectemp2.add( vecNear );
-		vectemp3.add( vecNear );
-
-		var planes = frustum.planes;
-
-		planes[ 0 ].setFromCoplanarPoints( vecNear, vecTopLeft, vecTopRight );
-		planes[ 1 ].setFromCoplanarPoints( vecNear, vecTopRight, vecDownRight );
-		planes[ 2 ].setFromCoplanarPoints( vecDownRight, vecDownLeft, vecNear );
-		planes[ 3 ].setFromCoplanarPoints( vecDownLeft, vecTopLeft, vecNear );
-		planes[ 4 ].setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
-		planes[ 5 ].setFromCoplanarPoints( vectemp3, vectemp2, vectemp1 );
-		planes[ 5 ].normal.multiplyScalar( - 1 );
+		if ( this.camera.isPerspectiveCamera ) {
+
+			tmpPoint.copy( startPoint );
+			tmpPoint.x = Math.min( startPoint.x, endPoint.x );
+			tmpPoint.y = Math.max( startPoint.y, endPoint.y );
+			endPoint.x = Math.max( startPoint.x, endPoint.x );
+			endPoint.y = Math.min( startPoint.y, endPoint.y );
+
+			vecNear.copy( this.camera.position );
+			vecTopLeft.copy( tmpPoint );
+			vecTopRight.set( endPoint.x, tmpPoint.y, 0 );
+			vecDownRight.copy( endPoint );
+			vecDownLeft.set( tmpPoint.x, endPoint.y, 0 );
+
+			vecTopLeft.unproject( this.camera );
+			vecTopRight.unproject( this.camera );
+			vecDownRight.unproject( this.camera );
+			vecDownLeft.unproject( this.camera );
+
+			vectemp1.copy( vecTopLeft ).sub( vecNear );
+			vectemp2.copy( vecTopRight ).sub( vecNear );
+			vectemp3.copy( vecDownRight ).sub( vecNear );
+			vectemp1.normalize();
+			vectemp2.normalize();
+			vectemp3.normalize();
+
+			vectemp1.multiplyScalar( this.deep );
+			vectemp2.multiplyScalar( this.deep );
+			vectemp3.multiplyScalar( this.deep );
+			vectemp1.add( vecNear );
+			vectemp2.add( vecNear );
+			vectemp3.add( vecNear );
+
+			var planes = frustum.planes;
+
+			planes[ 0 ].setFromCoplanarPoints( vecNear, vecTopLeft, vecTopRight );
+			planes[ 1 ].setFromCoplanarPoints( vecNear, vecTopRight, vecDownRight );
+			planes[ 2 ].setFromCoplanarPoints( vecDownRight, vecDownLeft, vecNear );
+			planes[ 3 ].setFromCoplanarPoints( vecDownLeft, vecTopLeft, vecNear );
+			planes[ 4 ].setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
+			planes[ 5 ].setFromCoplanarPoints( vectemp3, vectemp2, vectemp1 );
+			planes[ 5 ].normal.multiplyScalar( - 1 );
+
+		} else if ( this.camera.isOrthographicCamera ) {
+
+			if ( startPoint.equals( endPoint ) ) endPoint.addScalar( Number.EPSILON ); // avoid invalid frustum
+
+			var left = Math.min( startPoint.x, endPoint.x );
+			var top = Math.max( startPoint.y, endPoint.y );
+			var right = Math.max( startPoint.x, endPoint.x );
+			var down = Math.min( startPoint.y, endPoint.y );
+
+			vecTopLeft.set( left, top, - 1 );
+			vecTopRight.set( right, top, - 1 );
+			vecDownRight.set( right, down, - 1 );
+			vecDownLeft.set( left, down, - 1 );
+
+			vecFarTopLeft.set( left, top, 1 );
+			vecFarTopRight.set( right, top, 1 );
+			vecFarDownRight.set( right, down, 1 );
+			vecFarDownLeft.set( left, down, 1 );
+
+			vecTopLeft.unproject( this.camera );
+			vecTopRight.unproject( this.camera );
+			vecDownRight.unproject( this.camera );
+			vecDownLeft.unproject( this.camera );
+
+			vecFarTopLeft.unproject( this.camera );
+			vecFarTopRight.unproject( this.camera );
+			vecFarDownRight.unproject( this.camera );
+			vecFarDownLeft.unproject( this.camera );
+
+			var planes = frustum.planes;
+
+			planes[ 0 ].setFromCoplanarPoints( vecTopLeft, vecFarTopLeft, vecFarTopRight );
+			planes[ 1 ].setFromCoplanarPoints( vecTopRight, vecFarTopRight, vecFarDownRight );
+			planes[ 2 ].setFromCoplanarPoints( vecFarDownRight, vecFarDownLeft, vecDownLeft );
+			planes[ 3 ].setFromCoplanarPoints( vecFarDownLeft, vecFarTopLeft, vecTopLeft );
+			planes[ 4 ].setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
+			planes[ 5 ].setFromCoplanarPoints( vecFarDownRight, vecFarTopRight, vecFarTopLeft );
+			planes[ 5 ].normal.multiplyScalar( - 1 );
+
+		} else {
+
+			console.error( 'THREE.SelectionBox: Unsupported camera type.' );
+
+		}
 
 	};
 
 	SelectionBox.prototype.searchChildInFrustum = function ( frustum, object ) {
 
-		if ( object.isMesh ) {
+		if ( object.isMesh || object.isLine || object.isPoints ) {
 
 			if ( object.material !== undefined ) {
 
-				object.geometry.computeBoundingSphere();
+				if ( object.geometry.boundingSphere === null ) object.geometry.computeBoundingSphere();
 
 				center.copy( object.geometry.boundingSphere.center );