three.js - zoom extents Raytrace

by mmalex

HTML

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/renderers/Projector.js"></script>
<div style="position: fixed; z-index: 0; padding-left: 12px;">
Adjust camera extents<br /><br />
<button onclick="zoomExtents2()">
Zoom Extents
</button>
</div>

CSS

body {
  font-family: monospace;
  font-size: 11px;
  overflow: hidden;
  padding: 0;
  margin: 0;
}

JavaScript

var renderer;
var camera;
var scene;
var orbit;
var cube;

function zoomExtents2() {
  let bbox = cube.geometry.boundingBox;
  let center = bbox.min.clone().add(bbox.max).multiplyScalar(0.5);
  center = cube.localToWorld(center);

  let cameraDir = new THREE.Vector3();
  camera.getWorldDirection(cameraDir);

  let plane = new THREE.Plane();
  plane.setFromNormalAndCoplanarPoint(cameraDir.clone().negate(), center);

  var helper = new THREE.PlaneHelper(plane, 20, 0xffff00);
  //scene.add(helper);

  let verts = cube.geometry.attributes.position.array;

  let localVert = new THREE.Vector3();
  let ray = new THREE.Ray();
  let intersections = [];
  for (let i = 0; i < verts.length; i += 3) {
    let v0 = verts[i + 0];
    let v1 = verts[i + 1];
    let v2 = verts[i + 2];
    localVert.set(v0, v1, v2);
    let worldVert = cube.localToWorld(localVert);
    let rayDir = worldVert.clone().sub(camera.position).normalize();
    ray.set(camera.position, rayDir);

    let intersection = new THREE.Vector3();
    ray.intersectPlane(plane, intersection);
    intersections.push(intersection);
  }

  var bbox2 = new THREE.Box3();

  for (let p of intersections) {
    bbox2.expandByPoint(p);
  }

  let middle = new THREE.Vector3();
  bbox2.getCenter(middle);

  camera.lookAt(middle);
  orbit.target.copy(middle);

  orbit.update();
}

scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(54, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 15;
camera.position.y = 15;
camera.position.z = 15;
camera.lookAt(0, 0, 0);

renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0xfefefe));
document.body.appendChild(renderer.domElement);

orbit = new THREE.OrbitControls(camera, renderer.domElement);

// create light
{
  var spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(0, 100, 50);
  spotLight.castShadow = true;
 ...