WebVRCamera.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.WebVRCamera = function ( display, renderer ) {
  5. var scope = this;
  6. var frameData = null;
  7. if ( 'VRFrameData' in window ) {
  8. frameData = new window.VRFrameData();
  9. }
  10. var eyeTranslationL = new THREE.Vector3();
  11. var eyeTranslationR = new THREE.Vector3();
  12. var cameraL = new THREE.PerspectiveCamera();
  13. cameraL.bounds = new THREE.Vector4( 0.0, 0.0, 0.5, 1.0 );
  14. cameraL.layers.enable( 1 );
  15. var cameraR = new THREE.PerspectiveCamera();
  16. cameraR.bounds = new THREE.Vector4( 0.5, 0.0, 0.5, 1.0 );
  17. cameraR.layers.enable( 2 );
  18. //
  19. var currentSize, currentPixelRatio;
  20. function onVRDisplayPresentChange() {
  21. if ( display.isPresenting ) {
  22. var eyeParameters = display.getEyeParameters( 'left' );
  23. var renderWidth = eyeParameters.renderWidth;
  24. var renderHeight = eyeParameters.renderHeight;
  25. currentPixelRatio = renderer.getPixelRatio();
  26. currentSize = renderer.getSize();
  27. renderer.setPixelRatio( 1 );
  28. renderer.setSize( renderWidth * 2, renderHeight, false );
  29. scope.enabled = true;
  30. } else if ( scope.enabled ) {
  31. scope.enabled = false;
  32. renderer.setPixelRatio( currentPixelRatio );
  33. renderer.setSize( currentSize.width, currentSize.height, true );
  34. }
  35. }
  36. window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
  37. //
  38. THREE.ArrayCamera.call( this, [ cameraL, cameraR ] );
  39. //
  40. this.onBeforeRender = function () {
  41. display.depthNear = scope.near;
  42. display.depthFar = scope.far;
  43. display.getFrameData( frameData );
  44. //
  45. var pose = frameData.pose;
  46. if ( pose.orientation !== null ) {
  47. scope.quaternion.fromArray( pose.orientation );
  48. }
  49. if ( pose.position !== null ) {
  50. scope.position.fromArray( pose.position );
  51. } else {
  52. scope.position.set( 0, 0, 0 );
  53. }
  54. //
  55. var eyeParamsL = display.getEyeParameters( 'left' );
  56. var eyeParamsR = display.getEyeParameters( 'right' );
  57. eyeTranslationL.fromArray( eyeParamsL.offset );
  58. eyeTranslationR.fromArray( eyeParamsR.offset );
  59. cameraL.position.copy( scope.position );
  60. cameraL.quaternion.copy( scope.quaternion );
  61. cameraL.scale.copy( scope.scale );
  62. cameraR.position.copy( scope.position );
  63. cameraR.quaternion.copy( scope.quaternion );
  64. cameraR.scale.copy( scope.scale );
  65. cameraL.translateOnAxis( eyeTranslationL, cameraL.scale.x );
  66. cameraR.translateOnAxis( eyeTranslationR, cameraR.scale.x );
  67. cameraL.updateMatrixWorld();
  68. cameraL.matrixWorldInverse.getInverse( cameraL.matrixWorld );
  69. cameraR.updateMatrixWorld();
  70. cameraR.matrixWorldInverse.getInverse( cameraR.matrixWorld );
  71. cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
  72. cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
  73. // HACK @mrdoob
  74. // Ideally we'll merge both projection matrices so we can frustum cull
  75. scope.projectionMatrix.copy( cameraL.projectionMatrix );
  76. //
  77. var layers = display.getLayers();
  78. if ( layers.length ) {
  79. var layer = layers[ 0 ];
  80. if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) {
  81. cameraL.bounds.fromArray( layer.leftBounds );
  82. }
  83. if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) {
  84. cameraR.bounds.fromArray( layer.rightBounds );
  85. }
  86. }
  87. };
  88. this.onAfterRender = function () {
  89. if ( display.isPresenting ) display.submitFrame();
  90. };
  91. };
  92. THREE.WebVRCamera.prototype = Object.assign( Object.create( THREE.ArrayCamera.prototype ), {
  93. constructor: THREE.WebVRCamera,
  94. isWebVRCamera: true
  95. } );