12
12
THREE . VREffect = function ( renderer , onError ) {
13
13
14
14
var vrHMD ;
15
- var eyeTranslationL , eyeFOVL , renderRectL ;
16
- var eyeTranslationR , eyeFOVR , renderRectR ;
15
+ var deprecatedAPI = false ;
16
+ var eyeTranslationL = new THREE . Vector3 ( ) ;
17
+ var eyeTranslationR = new THREE . Vector3 ( ) ;
18
+ var renderRectL , renderRectR ;
19
+ var eyeFOVL , eyeFOVR ;
17
20
18
21
function gotVRDevices ( devices ) {
19
22
20
23
for ( var i = 0 ; i < devices . length ; i ++ ) {
21
24
22
- if ( devices [ i ] instanceof HMDVRDevice ) {
25
+ if ( 'VRDisplay' in window && devices [ i ] instanceof VRDisplay ) {
23
26
24
27
vrHMD = devices [ i ] ;
28
+ deprecatedAPI = false ;
29
+ break ; // We keep the first we encounter
30
+
31
+ } else if ( 'HMDVRDevice' in window && devices [ i ] instanceof HMDVRDevice ) {
25
32
33
+ vrHMD = devices [ i ] ;
34
+ deprecatedAPI = true ;
26
35
break ; // We keep the first we encounter
27
36
28
37
}
@@ -37,8 +46,13 @@ THREE.VREffect = function ( renderer, onError ) {
37
46
38
47
}
39
48
40
- if ( navigator . getVRDevices ) {
49
+ if ( navigator . getVRDisplays ) {
50
+
51
+ navigator . getVRDisplays ( ) . then ( gotVRDevices ) ;
52
+
53
+ } else if ( navigator . getVRDevices ) {
41
54
55
+ // Deprecated API.
42
56
navigator . getVRDevices ( ) . then ( gotVRDevices ) ;
43
57
44
58
}
@@ -55,31 +69,90 @@ THREE.VREffect = function ( renderer, onError ) {
55
69
56
70
// fullscreen
57
71
58
- var isFullscreen = false ;
72
+ var isPresenting = false ;
59
73
60
74
var canvas = renderer . domElement ;
61
75
var fullscreenchange = canvas . mozRequestFullScreen ? 'mozfullscreenchange' : 'webkitfullscreenchange' ;
62
76
63
- document . addEventListener ( fullscreenchange , function ( event ) {
77
+ document . addEventListener ( fullscreenchange , function ( ) {
64
78
65
- isFullscreen = document . mozFullScreenElement || document . webkitFullscreenElement ;
79
+ if ( vrHMD && deprecatedAPI ) {
80
+
81
+ isPresenting = document . mozFullScreenElement || document . webkitFullscreenElement ;
82
+
83
+ }
84
+
85
+ } , false ) ;
86
+
87
+ window . addEventListener ( 'vrdisplaypresentchange' , function ( ) {
88
+
89
+ isPresenting = vrHMD && vrHMD . isPresenting ;
66
90
67
91
} , false ) ;
68
92
69
93
this . setFullScreen = function ( boolean ) {
70
94
71
- if ( vrHMD === undefined ) return ;
72
- if ( isFullscreen === boolean ) return ;
95
+ return new Promise ( function ( resolve , reject ) {
96
+
97
+ if ( vrHMD === undefined ) {
73
98
74
- if ( canvas . mozRequestFullScreen ) {
99
+ reject ( new Error ( 'No VR hardware found.' ) ) ;
100
+ return ;
75
101
76
- canvas . mozRequestFullScreen ( { vrDisplay : vrHMD } ) ;
102
+ }
103
+ if ( isPresenting === boolean ) {
104
+
105
+ resolve ( ) ;
106
+ return ;
77
107
78
- } else if ( canvas . webkitRequestFullscreen ) {
108
+ }
79
109
80
- canvas . webkitRequestFullscreen ( { vrDisplay : vrHMD } ) ;
110
+ if ( ! deprecatedAPI ) {
81
111
82
- }
112
+ if ( boolean ) {
113
+
114
+ resolve ( vrHMD . requestPresent ( { source : canvas } ) ) ;
115
+
116
+ } else {
117
+
118
+ resolve ( vrHMD . exitPresent ( ) ) ;
119
+
120
+ }
121
+
122
+ } else {
123
+
124
+ if ( canvas . mozRequestFullScreen ) {
125
+
126
+ canvas . mozRequestFullScreen ( { vrDisplay : vrHMD } ) ;
127
+ resolve ( ) ;
128
+
129
+ } else if ( canvas . webkitRequestFullscreen ) {
130
+
131
+ canvas . webkitRequestFullscreen ( { vrDisplay : vrHMD } ) ;
132
+ resolve ( ) ;
133
+
134
+ } else {
135
+
136
+ console . error ( 'No compatible requestFullscreen method found.' ) ;
137
+ reject ( new Error ( 'No compatible requestFullscreen method found.' ) ) ;
138
+
139
+ }
140
+
141
+ }
142
+
143
+ } ) ;
144
+
145
+ } ;
146
+
147
+ this . requestPresent = function ( ) {
148
+
149
+ return this . setFullScreen ( true ) ;
150
+
151
+ } ;
152
+
153
+ this . exitPresent = function ( ) {
154
+
155
+ return this . setFullScreen ( false ) ;
83
156
84
157
} ;
85
158
@@ -93,17 +166,35 @@ THREE.VREffect = function ( renderer, onError ) {
93
166
94
167
this . render = function ( scene , camera ) {
95
168
96
- if ( vrHMD ) {
169
+ if ( vrHMD && isPresenting ) {
170
+
171
+ var autoUpdate = scene . autoUpdate ;
172
+
173
+ if ( autoUpdate ) {
174
+
175
+ scene . updateMatrixWorld ( ) ;
176
+ scene . autoUpdate = false ;
177
+
178
+ }
97
179
98
180
var eyeParamsL = vrHMD . getEyeParameters ( 'left' ) ;
99
181
var eyeParamsR = vrHMD . getEyeParameters ( 'right' ) ;
100
182
101
- eyeTranslationL = eyeParamsL . eyeTranslation ;
102
- eyeTranslationR = eyeParamsR . eyeTranslation ;
103
- eyeFOVL = eyeParamsL . recommendedFieldOfView ;
104
- eyeFOVR = eyeParamsR . recommendedFieldOfView ;
105
- renderRectL = eyeParamsL . renderRect ;
106
- renderRectR = eyeParamsR . renderRect ;
183
+ if ( ! deprecatedAPI ) {
184
+
185
+ eyeTranslationL . fromArray ( eyeParamsL . offset ) ;
186
+ eyeTranslationR . fromArray ( eyeParamsR . offset ) ;
187
+ eyeFOVL = eyeParamsL . fieldOfView ;
188
+ eyeFOVR = eyeParamsR . fieldOfView ;
189
+
190
+ } else {
191
+
192
+ eyeTranslationL . copy ( eyeParamsL . eyeTranslation ) ;
193
+ eyeTranslationR . copy ( eyeParamsR . eyeTranslation ) ;
194
+ eyeFOVL = eyeParamsL . recommendedFieldOfView ;
195
+ eyeFOVR = eyeParamsR . recommendedFieldOfView ;
196
+
197
+ }
107
198
108
199
if ( Array . isArray ( scene ) ) {
109
200
@@ -112,7 +203,11 @@ THREE.VREffect = function ( renderer, onError ) {
112
203
113
204
}
114
205
206
+ // When rendering we don't care what the recommended size is, only what the actual size
207
+ // of the backbuffer is.
115
208
var size = renderer . getSize ( ) ;
209
+ renderRectL = { x : 0 , y : 0 , width : size . width / 2 , height : size . height } ;
210
+ renderRectR = { x : size . width / 2 , y : 0 , width : size . width / 2 , height : size . height } ;
116
211
117
212
renderer . setScissorTest ( true ) ;
118
213
renderer . clear ( ) ;
@@ -129,28 +224,29 @@ THREE.VREffect = function ( renderer, onError ) {
129
224
cameraR . translateX ( eyeTranslationR . x * this . scale ) ;
130
225
131
226
// render left eye
132
- if ( renderRectL === undefined ) {
133
-
134
- renderRectL = { x : 0 , y : 0 , width : size . width / 2 , height : size . height } ;
135
-
136
- }
137
227
renderer . setViewport ( renderRectL . x , renderRectL . y , renderRectL . width , renderRectL . height ) ;
138
228
renderer . setScissor ( renderRectL . x , renderRectL . y , renderRectL . width , renderRectL . height ) ;
139
229
renderer . render ( scene , cameraL ) ;
140
230
141
231
// render right eye
142
- if ( renderRectR === undefined ) {
143
-
144
- renderRectR = { x : size . width / 2 , y : 0 , width : size . width / 2 , height : size . height } ;
145
-
146
- }
147
-
148
232
renderer . setViewport ( renderRectR . x , renderRectR . y , renderRectR . width , renderRectR . height ) ;
149
233
renderer . setScissor ( renderRectR . x , renderRectR . y , renderRectR . width , renderRectR . height ) ;
150
234
renderer . render ( scene , cameraR ) ;
151
235
152
236
renderer . setScissorTest ( false ) ;
153
237
238
+ if ( autoUpdate ) {
239
+
240
+ scene . autoUpdate = true ;
241
+
242
+ }
243
+
244
+ if ( ! deprecatedAPI ) {
245
+
246
+ vrHMD . submitFrame ( ) ;
247
+
248
+ }
249
+
154
250
return ;
155
251
156
252
}
0 commit comments