Three.js:"选择工具"如何检测2D正方形和3D对象的交集

Cap*_*ous 5 javascript intersection three.js raycasting

基本上我想要创建:

我有一个带有对象的3D地图,我想选择我屏幕上的2D框x1,y1到x2,y2中的所有对象.

任何想法如何做到这一点,因为我对如何开始毫无头绪.

提前致谢!

prevX并且prevY是鼠标按下的坐标:

function onDocumentMouseUp(event) {
  event.preventDefault();

  var x = (event.clientX / window.innerWidth) * 2 - 1;
  var y = -(event.clientY / window.innerHeight) * 2 + 1;

  var width = (x - prevX); //* window.innerWidth;
  var height = (y - prevY); //* window.innerHeight;
  var dx = prevX; //* window.innerWidth;
  var dy = prevY; //* window.innerHeight;

  console.log(
    dx + ',' + 
    dy + "," + 
    (dx + width) + "," + 
    (dy + height) + 
    ", width=" + width + 
    ", height=" + height
  );
  var topLeftCorner3D = new THREE.Vector3(dx, dy, 1).unproject(
    camera);
  var topRightCorner3D = new THREE.Vector3(dx + width, dy, 1)
    .unproject(camera);
  var bottomLeftCorner3D = new THREE.Vector3(dx, dy + height,
    1).unproject(camera);
  var bottomRightCorner3D = new THREE.Vector3(dx + width, dy +
    height, 1).unproject(camera);

  var topPlane = new THREE.Plane();
  var rightPlane = new THREE.Plane();
  var bottomPlane = new THREE.Plane();
  var leftPlane = new THREE.Plane();

  topPlane.setFromCoplanarPoints(camera.position,
    topLeftCorner3D, topRightCorner3D);
  rightPlane.setFromCoplanarPoints(camera.position,
    topRightCorner3D, bottomRightCorner3D);
  bottomPlane.setFromCoplanarPoints(camera.position,
    bottomRightCorner3D, bottomLeftCorner3D);
  leftPlane.setFromCoplanarPoints(camera.position,
    bottomLeftCorner3D, topLeftCorner3D);

  //var frustum = new THREE.Frustum( topPlane, bottomPlane, leftPlane, rightPlane, nearPlane, farPlane);

  function isObjectInFrustum(object3D) {
    var sphere = object3D.geometry.boundingSphere;
    var center = sphere.center;
    var negRadius = -sphere.radius;

    if (topPlane.distanceToPoint(center) < negRadius) { return false; }
    if (bottomPlane.distanceToPoint(center) < negRadius) { return false; }
    if (rightPlane.distanceToPoint(center) < negRadius) { return false; }
    if (leftPlane.distanceToPoint(center) < negRadius) { return false; }

    return true;
  }
  var matches = [];
  for (var i = 0; i < window.objects.length; i++) {

    if (isObjectInFrustum(window.objects[i])) {
      window.objects[i].material = window.selectedMaterial;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

elc*_*iga 1

您可以使用对象的边界框。THREE.Geometry包含一个boundingBox属性。这是null默认的,您应该通过computeBoundingBox()直接调用来计算它。

scene.traverse( function ( node ) {
    if ( node.geometry )
         node.geometry.computeBoundingBox();
} );
Run Code Online (Sandbox Code Playgroud)

获得边界框后,边界框 2D 坐标为(如果“y”是向上轴):

mesh.geometry.boundingBox.min.x
mesh.geometry.boundingBox.min.z
mesh.geometry.boundingBox.max.x
mesh.geometry.boundingBox.max.z
Run Code Online (Sandbox Code Playgroud)

请参阅http://trijs.org/docs/#Reference/Core/Geometry

(但是,如果您需要非矩形网格的精确结果,则需要进一步计算)