three.js - zoom extents Sphere

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;">
<br />
<button onclick="zoomExtents()">
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 object1;

function zoomExtents() {
  let vFoV = camera.getEffectiveFOV();
  let hFoV = camera.fov * camera.aspect;

  let FoV = Math.min(vFoV, hFoV);
  let FoV2 = FoV / 2;

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

  let bb = object1.geometry.boundingBox;
  let bs = object1.geometry.boundingSphere;
  let bsWorld = bs.center.clone();
  object1.localToWorld(bsWorld);

  let th = FoV2 * Math.PI / 180.0;
  let sina = Math.sin(th);
  let R = bs.radius;
  let FL = R / sina;

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

  let cameraOffs = cameraDir.clone();
  cameraOffs.multiplyScalar(-FL);
  let newCameraPos = bsWorld.clone().add(cameraOffs);

  camera.position.copy(newCameraPos);
  camera.lookAt(bsWorld);
  orbit.target.copy(bsWorld);

  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;
  spotLight.shadow.mapSize.width = 1024;
  spotLight.shadow.mapSize.height = 1024;
  spotLight.shadow.camera.near = 500;
  spotLight.shadow.camera.far = 4000;
  spotLight.shadow.camera.fov = 30;
  scene.add(spotLight);
}

var root = new THREE.Object3D();
scene.add(root);

function CustomSinCurve(scale) {
  THREE.Curve.call(this);
  this.scale = (scale === undefined) ? 1 : scale;
}

CustomSinCurve.prototype = Object.create(THREE.Curve.prototype);
CustomSinCurve.prototype.constructor =...