PerspectiveCamera.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. * @author greggman / http://games.greggman.com/
  4. * @author zz85 / http://www.lab4games.net/zz85/blog
  5. */
  6. THREE.PerspectiveCamera = function ( fov, aspect, near, far ) {
  7. THREE.Camera.call( this );
  8. this.fov = fov !== undefined ? fov : 50;
  9. this.aspect = aspect !== undefined ? aspect : 1;
  10. this.near = near !== undefined ? near : 0.1;
  11. this.far = far !== undefined ? far : 2000;
  12. this.updateProjectionMatrix();
  13. };
  14. THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype );
  15. /**
  16. * Uses Focal Length (in mm) to estimate and set FOV
  17. * 35mm (fullframe) camera is used if frame size is not specified;
  18. * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
  19. */
  20. THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
  21. if ( frameHeight === undefined ) frameHeight = 24;
  22. this.fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) );
  23. this.updateProjectionMatrix();
  24. }
  25. /**
  26. * Sets an offset in a larger frustum. This is useful for multi-window or
  27. * multi-monitor/multi-machine setups.
  28. *
  29. * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
  30. * the monitors are in grid like this
  31. *
  32. * +---+---+---+
  33. * | A | B | C |
  34. * +---+---+---+
  35. * | D | E | F |
  36. * +---+---+---+
  37. *
  38. * then for each monitor you would call it like this
  39. *
  40. * var w = 1920;
  41. * var h = 1080;
  42. * var fullWidth = w * 3;
  43. * var fullHeight = h * 2;
  44. *
  45. * --A--
  46. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
  47. * --B--
  48. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
  49. * --C--
  50. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
  51. * --D--
  52. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
  53. * --E--
  54. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
  55. * --F--
  56. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
  57. *
  58. * Note there is no reason monitors have to be the same size or in a grid.
  59. */
  60. THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) {
  61. this.fullWidth = fullWidth;
  62. this.fullHeight = fullHeight;
  63. this.x = x;
  64. this.y = y;
  65. this.width = width;
  66. this.height = height;
  67. this.updateProjectionMatrix();
  68. };
  69. THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () {
  70. if ( this.fullWidth ) {
  71. var aspect = this.fullWidth / this.fullHeight;
  72. var top = Math.tan( THREE.Math.degToRad( this.fov * 0.5 ) ) * this.near;
  73. var bottom = -top;
  74. var left = aspect * bottom;
  75. var right = aspect * top;
  76. var width = Math.abs( right - left );
  77. var height = Math.abs( top - bottom );
  78. this.projectionMatrix.makeFrustum(
  79. left + this.x * width / this.fullWidth,
  80. left + ( this.x + this.width ) * width / this.fullWidth,
  81. top - ( this.y + this.height ) * height / this.fullHeight,
  82. top - this.y * height / this.fullHeight,
  83. this.near,
  84. this.far
  85. );
  86. } else {
  87. this.projectionMatrix.makePerspective( this.fov, this.aspect, this.near, this.far );
  88. }
  89. };
  90. THREE.PerspectiveCamera.prototype.clone = function () {
  91. var camera = new THREE.PerspectiveCamera();
  92. THREE.Camera.prototype.clone.call( this, camera );
  93. camera.fov = this.fov;
  94. camera.aspect = this.aspect;
  95. camera.near = this.near;
  96. camera.far = this.far;
  97. return camera;
  98. };