CameraUtils.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. ( function () {
  2. const _va = /*@__PURE__*/new THREE.Vector3(),
  3. // from pe to pa
  4. _vb = /*@__PURE__*/new THREE.Vector3(),
  5. // from pe to pb
  6. _vc = /*@__PURE__*/new THREE.Vector3(),
  7. // from pe to pc
  8. _vr = /*@__PURE__*/new THREE.Vector3(),
  9. // right axis of screen
  10. _vu = /*@__PURE__*/new THREE.Vector3(),
  11. // up axis of screen
  12. _vn = /*@__PURE__*/new THREE.Vector3(),
  13. // normal vector of screen
  14. _vec = /*@__PURE__*/new THREE.Vector3(),
  15. // temporary vector
  16. _quat = /*@__PURE__*/new THREE.Quaternion(); // temporary quaternion
  17. /** Set a PerspectiveCamera's projectionMatrix and quaternion
  18. * to exactly frame the corners of an arbitrary rectangle.
  19. * NOTE: This function ignores the standard parameters;
  20. * do not call updateProjectionMatrix() after this!
  21. * @param {Vector3} bottomLeftCorner
  22. * @param {Vector3} bottomRightCorner
  23. * @param {Vector3} topLeftCorner
  24. * @param {boolean} estimateViewFrustum */
  25. function frameCorners( camera, bottomLeftCorner, bottomRightCorner, topLeftCorner, estimateViewFrustum = false ) {
  26. const pa = bottomLeftCorner,
  27. pb = bottomRightCorner,
  28. pc = topLeftCorner;
  29. const pe = camera.position; // eye position
  30. const n = camera.near; // distance of near clipping plane
  31. const f = camera.far; //distance of far clipping plane
  32. _vr.copy( pb ).sub( pa ).normalize();
  33. _vu.copy( pc ).sub( pa ).normalize();
  34. _vn.crossVectors( _vr, _vu ).normalize();
  35. _va.copy( pa ).sub( pe ); // from pe to pa
  36. _vb.copy( pb ).sub( pe ); // from pe to pb
  37. _vc.copy( pc ).sub( pe ); // from pe to pc
  38. const d = - _va.dot( _vn ); // distance from eye to screen
  39. const l = _vr.dot( _va ) * n / d; // distance to left screen edge
  40. const r = _vr.dot( _vb ) * n / d; // distance to right screen edge
  41. const b = _vu.dot( _va ) * n / d; // distance to bottom screen edge
  42. const t = _vu.dot( _vc ) * n / d; // distance to top screen edge
  43. // Set the camera rotation to match the focal plane to the corners' plane
  44. _quat.setFromUnitVectors( _vec.set( 0, 1, 0 ), _vu );
  45. camera.quaternion.setFromUnitVectors( _vec.set( 0, 0, 1 ).applyQuaternion( _quat ), _vn ).multiply( _quat ); // Set the off-axis projection matrix to match the corners
  46. camera.projectionMatrix.set( 2.0 * n / ( r - l ), 0.0, ( r + l ) / ( r - l ), 0.0, 0.0, 2.0 * n / ( t - b ), ( t + b ) / ( t - b ), 0.0, 0.0, 0.0, ( f + n ) / ( n - f ), 2.0 * f * n / ( n - f ), 0.0, 0.0, - 1.0, 0.0 );
  47. camera.projectionMatrixInverse.copy( camera.projectionMatrix ).invert(); // FoV estimation to fix frustum culling
  48. if ( estimateViewFrustum ) {
  49. // Set fieldOfView to a conservative estimate
  50. // to make frustum tall/wide enough to encompass it
  51. camera.fov = THREE.MathUtils.RAD2DEG / Math.min( 1.0, camera.aspect ) * Math.atan( ( _vec.copy( pb ).sub( pa ).length() + _vec.copy( pc ).sub( pa ).length() ) / _va.length() );
  52. }
  53. }
  54. THREE.CameraUtils = {};
  55. THREE.CameraUtils.frameCorners = frameCorners;
  56. } )();