1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/**
* @author HypnosNova / https://www.threejs.org.cn/gallery
* This is a class to check whether objects are in a selection area in 3D space
*/
import {
Frustum,
Vector3
} from "../../../build/three.module.js";
var SelectionBox = ( function () {
var frustum = new Frustum();
var center = new Vector3();
var tmpPoint = new Vector3();
var vecNear = new Vector3();
var vecTopLeft = new Vector3();
var vecTopRight = new Vector3();
var vecDownRight = new Vector3();
var vecDownLeft = new Vector3();
var vectemp1 = new Vector3();
var vectemp2 = new Vector3();
var vectemp3 = new Vector3();
function SelectionBox( camera, scene, deep ) {
this.camera = camera;
this.scene = scene;
this.startPoint = new Vector3();
this.endPoint = new Vector3();
this.collection = [];
this.deep = deep || Number.MAX_VALUE;
}
SelectionBox.prototype.select = function ( startPoint, endPoint ) {
this.startPoint = startPoint || this.startPoint;
this.endPoint = endPoint || this.endPoint;
this.collection = [];
this.updateFrustum( this.startPoint, this.endPoint );
this.searchChildInFrustum( frustum, this.scene );
return this.collection;
};
SelectionBox.prototype.updateFrustum = function ( startPoint, endPoint ) {
startPoint = startPoint || this.startPoint;
endPoint = endPoint || this.endPoint;
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 );
};
SelectionBox.prototype.searchChildInFrustum = function ( frustum, object ) {
if ( object.isMesh ) {
if ( object.material !== undefined ) {
object.geometry.computeBoundingSphere();
center.copy( object.geometry.boundingSphere.center );
center.applyMatrix4( object.matrixWorld );
if ( frustum.containsPoint( center ) ) {
this.collection.push( object );
}
}
}
if ( object.children.length > 0 ) {
for ( var x = 0; x < object.children.length; x ++ ) {
this.searchChildInFrustum( frustum, object.children[ x ] );
}
}
};
return SelectionBox;
} )();
export { SelectionBox };
|