Skip to content

Commit 3c904f3

Browse files
committed
WebVR: Moved setProjectionFromUnion method to internal WebVRUtils.
1 parent f565ac4 commit 3c904f3

File tree

4 files changed

+72
-67
lines changed

4 files changed

+72
-67
lines changed

src/cameras/ArrayCamera.js

Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
*/
44

55
import { PerspectiveCamera } from './PerspectiveCamera.js';
6-
import { Vector3 } from '../math/Vector3.js';
76

87
function ArrayCamera( array ) {
98

@@ -17,70 +16,7 @@ ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototyp
1716

1817
constructor: ArrayCamera,
1918

20-
isArrayCamera: true,
21-
22-
/**
23-
* Assumes 2 cameras that are perpendicular and share an X-axis, and that
24-
* the cameras' projection and world matrices have already been set.
25-
* And that near and far planes are identical for both cameras.
26-
*/
27-
setProjectionFromUnion: function () {
28-
29-
var cameraLPos = new Vector3();
30-
var cameraRPos = new Vector3();
31-
32-
return function () {
33-
34-
cameraLPos.setFromMatrixPosition( this.cameras[ 0 ].matrixWorld );
35-
cameraRPos.setFromMatrixPosition( this.cameras[ 1 ].matrixWorld );
36-
37-
var ipd = cameraLPos.distanceTo( cameraRPos );
38-
39-
var projL = this.cameras[ 0 ].projectionMatrix;
40-
var projR = this.cameras[ 1 ].projectionMatrix;
41-
42-
// VR systems will have identical far and near planes, and
43-
// most likely identical top and bottom frustum extents.
44-
// via: https://computergraphics.stackexchange.com/a/4765
45-
var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
46-
var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
47-
48-
var leftFovL = ( projL[ 8 ] - 1 ) / projL[ 0 ];
49-
var rightFovR = ( projR[ 8 ] + 1 ) / projR[ 0 ];
50-
var leftL = leftFovL * near;
51-
var rightR = rightFovR * near;
52-
var topL = near * ( projL[ 9 ] + 1 ) / projL[ 5 ];
53-
var topR = near * ( projR[ 9 ] + 1 ) / projR[ 5 ];
54-
var bottomL = near * ( projL[ 9 ] - 1 ) / projL[ 5 ];
55-
var bottomR = near * ( projR[ 9 ] - 1 ) / projR[ 5 ];
56-
57-
// Calculate the new camera's position offset from the
58-
// left camera.
59-
var zOffset = ipd / ( leftFovL + rightFovR );
60-
var xOffset = zOffset * leftFovL;
61-
62-
// TODO: Better way to apply this offset?
63-
this.cameras[ 0 ].matrixWorld.decompose( this.position, this.quaternion, this.scale );
64-
this.translateX( xOffset );
65-
this.translateZ( - zOffset );
66-
this.matrixWorld.compose( this.position, this.quaternion, this.scale );
67-
this.matrixWorldInverse.getInverse( this.matrixWorld );
68-
69-
// Find the union of the frustum values of the cameras and scale
70-
// the values so that the near plane's position does not change in world space,
71-
// although must now be relative to the new union camera.
72-
var near2 = near + zOffset;
73-
var far2 = far + zOffset;
74-
var left = leftL - xOffset;
75-
var right = rightR + ( ipd - xOffset );
76-
var top = Math.max( topL, topR );
77-
var bottom = Math.min( bottomL, bottomR );
78-
79-
this.projectionMatrix.makePerspective( left, right, top, bottom, near2, far2 );
80-
81-
};
82-
83-
}(),
19+
isArrayCamera: true
8420

8521
} );
8622

src/renderers/webvr/WebVRManager.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Quaternion } from '../../math/Quaternion.js';
1010
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
1111
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
1212
import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
13+
import { setProjectionFromUnion } from './WebVRUtils.js';
1314

1415
function WebVRManager( renderer ) {
1516

@@ -323,7 +324,7 @@ function WebVRManager( renderer ) {
323324
cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
324325
cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );
325326

326-
cameraVR.setProjectionFromUnion();
327+
setProjectionFromUnion( cameraVR, cameraL, cameraR );
327328

328329
//
329330

src/renderers/webvr/WebVRUtils.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @author jsantell / https://www.jsantell.com/
3+
* @author mrdoob / http://mrdoob.com/
4+
*/
5+
6+
import { Vector3 } from '../../math/Vector3.js';
7+
8+
var cameraLPos = new Vector3();
9+
var cameraRPos = new Vector3();
10+
11+
/**
12+
* Assumes 2 cameras that are perpendicular and share an X-axis, and that
13+
* the cameras' projection and world matrices have already been set.
14+
* And that near and far planes are identical for both cameras.
15+
*/
16+
function setProjectionFromUnion( camera, cameraL, cameraR ) {
17+
18+
cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
19+
cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
20+
21+
var ipd = cameraLPos.distanceTo( cameraRPos );
22+
23+
var projL = cameraL.projectionMatrix;
24+
var projR = cameraR.projectionMatrix;
25+
26+
// VR systems will have identical far and near planes, and
27+
// most likely identical top and bottom frustum extents.
28+
// via: https://computergraphics.stackexchange.com/a/4765
29+
var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
30+
var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
31+
32+
var leftFovL = ( projL[ 8 ] - 1 ) / projL[ 0 ];
33+
var rightFovR = ( projR[ 8 ] + 1 ) / projR[ 0 ];
34+
var leftL = leftFovL * near;
35+
var rightR = rightFovR * near;
36+
var topL = near * ( projL[ 9 ] + 1 ) / projL[ 5 ];
37+
var topR = near * ( projR[ 9 ] + 1 ) / projR[ 5 ];
38+
var bottomL = near * ( projL[ 9 ] - 1 ) / projL[ 5 ];
39+
var bottomR = near * ( projR[ 9 ] - 1 ) / projR[ 5 ];
40+
41+
// Calculate the new camera's position offset from the
42+
// left camera.
43+
var zOffset = ipd / ( leftFovL + rightFovR );
44+
var xOffset = zOffset * leftFovL;
45+
46+
// TODO: Better way to apply this offset?
47+
cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
48+
camera.translateX( xOffset );
49+
camera.translateZ( - zOffset );
50+
camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale );
51+
camera.matrixWorldInverse.getInverse( camera.matrixWorld );
52+
53+
// Find the union of the frustum values of the cameras and scale
54+
// the values so that the near plane's position does not change in world space,
55+
// although must now be relative to the new union camera.
56+
var near2 = near + zOffset;
57+
var far2 = far + zOffset;
58+
var left = leftL - xOffset;
59+
var right = rightR + ( ipd - xOffset );
60+
var top = Math.max( topL, topR );
61+
var bottom = Math.min( bottomL, bottomR );
62+
63+
camera.projectionMatrix.makePerspective( left, right, top, bottom, near2, far2 );
64+
65+
}
66+
67+
export { setProjectionFromUnion };

src/renderers/webvr/WebXRManager.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Vector4 } from '../../math/Vector4.js';
77
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
88
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
99
import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
10+
import { setProjectionFromUnion } from './WebVRUtils.js';
1011

1112
function WebXRManager( renderer ) {
1213

@@ -181,7 +182,7 @@ function WebXRManager( renderer ) {
181182

182183
}
183184

184-
cameraVR.setProjectionFromUnion();
185+
setProjectionFromUnion( cameraVR, cameraL, cameraR );
185186

186187
return cameraVR;
187188

0 commit comments

Comments
 (0)