@epicgames-ps/lib-pixelstreamingfrontend-ue5.5 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/dist/commonjs/AFK/AFKController.js +109 -109
  2. package/dist/commonjs/Config/Config.js +559 -559
  3. package/dist/commonjs/Config/SettingBase.js +98 -98
  4. package/dist/commonjs/Config/SettingFlag.js +49 -49
  5. package/dist/commonjs/Config/SettingNumber.js +83 -83
  6. package/dist/commonjs/Config/SettingOption.js +84 -84
  7. package/dist/commonjs/Config/SettingText.js +42 -42
  8. package/dist/commonjs/DataChannel/DataChannelController.js +106 -106
  9. package/dist/commonjs/DataChannel/DataChannelLatencyTestController.js +94 -94
  10. package/dist/commonjs/DataChannel/DataChannelLatencyTestResults.js +18 -18
  11. package/dist/commonjs/DataChannel/DataChannelSender.js +43 -43
  12. package/dist/commonjs/DataChannel/InitialSettings.js +41 -41
  13. package/dist/commonjs/DataChannel/LatencyTestResults.js +60 -60
  14. package/dist/commonjs/FreezeFrame/FreezeFrame.js +93 -93
  15. package/dist/commonjs/FreezeFrame/FreezeFrameController.js +95 -95
  16. package/dist/commonjs/Inputs/GamepadController.js +188 -188
  17. package/dist/commonjs/Inputs/GamepadTypes.js +21 -21
  18. package/dist/commonjs/Inputs/IInputController.js +2 -2
  19. package/dist/commonjs/Inputs/InputClassesFactory.js +96 -96
  20. package/dist/commonjs/Inputs/KeyCodes.js +112 -112
  21. package/dist/commonjs/Inputs/KeyboardController.js +137 -137
  22. package/dist/commonjs/Inputs/MouseButtons.js +28 -28
  23. package/dist/commonjs/Inputs/MouseController.js +97 -97
  24. package/dist/commonjs/Inputs/MouseControllerHovering.js +93 -93
  25. package/dist/commonjs/Inputs/MouseControllerLocked.js +153 -153
  26. package/dist/commonjs/Inputs/SpecialKeyCodes.js +19 -19
  27. package/dist/commonjs/Inputs/TouchController.js +123 -123
  28. package/dist/commonjs/Inputs/TouchController.js.map +1 -1
  29. package/dist/commonjs/Inputs/TouchControllerFake.js +91 -91
  30. package/dist/commonjs/Inputs/XRGamepadController.js +124 -124
  31. package/dist/commonjs/PeerConnectionController/AggregatedStats.js +252 -252
  32. package/dist/commonjs/PeerConnectionController/CandidatePairStats.js +10 -10
  33. package/dist/commonjs/PeerConnectionController/CandidateStat.js +10 -10
  34. package/dist/commonjs/PeerConnectionController/CodecStats.js +10 -10
  35. package/dist/commonjs/PeerConnectionController/DataChannelStats.js +10 -10
  36. package/dist/commonjs/PeerConnectionController/InboundRTPStats.js +22 -22
  37. package/dist/commonjs/PeerConnectionController/InboundTrackStats.js +10 -10
  38. package/dist/commonjs/PeerConnectionController/OutBoundRTPStats.js +16 -16
  39. package/dist/commonjs/PeerConnectionController/PeerConnectionController.js +584 -584
  40. package/dist/commonjs/PeerConnectionController/SessionStats.js +10 -10
  41. package/dist/commonjs/PeerConnectionController/StreamStats.js +10 -10
  42. package/dist/commonjs/PixelStreaming/PixelStreaming.js +607 -607
  43. package/dist/commonjs/UI/OnScreenKeyboard.js +82 -82
  44. package/dist/commonjs/UeInstanceMessage/ResponseController.js +38 -38
  45. package/dist/commonjs/UeInstanceMessage/SendMessageController.js +120 -120
  46. package/dist/commonjs/UeInstanceMessage/StreamMessageController.js +210 -210
  47. package/dist/commonjs/UeInstanceMessage/ToStreamerMessagesController.js +49 -49
  48. package/dist/commonjs/Util/EventEmitter.js +386 -386
  49. package/dist/commonjs/Util/FileUtil.js +108 -108
  50. package/dist/commonjs/Util/IURLSearchParams.js +25 -25
  51. package/dist/commonjs/Util/InputCoordTranslator.js +49 -49
  52. package/dist/commonjs/Util/RTCUtils.js +40 -40
  53. package/dist/commonjs/VideoPlayer/StreamController.js +67 -67
  54. package/dist/commonjs/VideoPlayer/VideoPlayer.js +177 -177
  55. package/dist/commonjs/WebRtcPlayer/WebRtcPlayerController.js +1221 -1221
  56. package/dist/commonjs/WebXR/WebXRController.js +335 -335
  57. package/dist/commonjs/pixelstreamingfrontend.js +70 -70
  58. package/dist/esm/AFK/AFKController.js +105 -105
  59. package/dist/esm/Config/Config.js +551 -551
  60. package/dist/esm/Config/SettingBase.js +94 -94
  61. package/dist/esm/Config/SettingFlag.js +45 -45
  62. package/dist/esm/Config/SettingNumber.js +79 -79
  63. package/dist/esm/Config/SettingOption.js +80 -80
  64. package/dist/esm/Config/SettingText.js +38 -38
  65. package/dist/esm/DataChannel/DataChannelController.js +102 -102
  66. package/dist/esm/DataChannel/DataChannelLatencyTestController.js +90 -90
  67. package/dist/esm/DataChannel/DataChannelLatencyTestResults.js +14 -14
  68. package/dist/esm/DataChannel/DataChannelSender.js +39 -39
  69. package/dist/esm/DataChannel/InitialSettings.js +34 -34
  70. package/dist/esm/DataChannel/LatencyTestResults.js +56 -56
  71. package/dist/esm/FreezeFrame/FreezeFrame.js +89 -89
  72. package/dist/esm/FreezeFrame/FreezeFrameController.js +91 -91
  73. package/dist/esm/Inputs/GamepadController.js +184 -184
  74. package/dist/esm/Inputs/GamepadTypes.js +17 -17
  75. package/dist/esm/Inputs/IInputController.js +1 -1
  76. package/dist/esm/Inputs/InputClassesFactory.js +91 -91
  77. package/dist/esm/Inputs/KeyCodes.js +109 -109
  78. package/dist/esm/Inputs/KeyboardController.js +133 -133
  79. package/dist/esm/Inputs/MouseButtons.js +23 -23
  80. package/dist/esm/Inputs/MouseController.js +93 -93
  81. package/dist/esm/Inputs/MouseControllerHovering.js +89 -89
  82. package/dist/esm/Inputs/MouseControllerLocked.js +149 -149
  83. package/dist/esm/Inputs/SpecialKeyCodes.js +15 -15
  84. package/dist/esm/Inputs/TouchController.js +119 -119
  85. package/dist/esm/Inputs/TouchController.js.map +1 -1
  86. package/dist/esm/Inputs/TouchControllerFake.js +87 -87
  87. package/dist/esm/Inputs/XRGamepadController.js +120 -120
  88. package/dist/esm/PeerConnectionController/AggregatedStats.js +248 -248
  89. package/dist/esm/PeerConnectionController/CandidatePairStats.js +6 -6
  90. package/dist/esm/PeerConnectionController/CandidateStat.js +6 -6
  91. package/dist/esm/PeerConnectionController/CodecStats.js +6 -6
  92. package/dist/esm/PeerConnectionController/DataChannelStats.js +6 -6
  93. package/dist/esm/PeerConnectionController/InboundRTPStats.js +16 -16
  94. package/dist/esm/PeerConnectionController/InboundTrackStats.js +6 -6
  95. package/dist/esm/PeerConnectionController/OutBoundRTPStats.js +11 -11
  96. package/dist/esm/PeerConnectionController/PeerConnectionController.js +580 -580
  97. package/dist/esm/PeerConnectionController/SessionStats.js +6 -6
  98. package/dist/esm/PeerConnectionController/StreamStats.js +6 -6
  99. package/dist/esm/PixelStreaming/PixelStreaming.js +603 -603
  100. package/dist/esm/UI/OnScreenKeyboard.js +78 -78
  101. package/dist/esm/UeInstanceMessage/ResponseController.js +34 -34
  102. package/dist/esm/UeInstanceMessage/SendMessageController.js +116 -116
  103. package/dist/esm/UeInstanceMessage/StreamMessageController.js +205 -205
  104. package/dist/esm/UeInstanceMessage/ToStreamerMessagesController.js +45 -45
  105. package/dist/esm/Util/EventEmitter.js +345 -345
  106. package/dist/esm/Util/FileUtil.js +103 -103
  107. package/dist/esm/Util/IURLSearchParams.js +21 -21
  108. package/dist/esm/Util/InputCoordTranslator.js +45 -45
  109. package/dist/esm/Util/RTCUtils.js +36 -36
  110. package/dist/esm/VideoPlayer/StreamController.js +63 -63
  111. package/dist/esm/VideoPlayer/VideoPlayer.js +173 -173
  112. package/dist/esm/WebRtcPlayer/WebRtcPlayerController.js +1217 -1217
  113. package/dist/esm/WebXR/WebXRController.js +331 -331
  114. package/dist/esm/pixelstreamingfrontend.js +24 -24
  115. package/dist/types/AFK/AFKController.d.ts +38 -38
  116. package/dist/types/Config/Config.d.ts +220 -220
  117. package/dist/types/Config/SettingBase.d.ts +43 -43
  118. package/dist/types/Config/SettingFlag.d.ts +24 -24
  119. package/dist/types/Config/SettingNumber.d.ts +41 -41
  120. package/dist/types/Config/SettingOption.d.ts +41 -41
  121. package/dist/types/Config/SettingText.d.ts +21 -21
  122. package/dist/types/DataChannel/DataChannelController.d.ts +59 -59
  123. package/dist/types/DataChannel/DataChannelLatencyTestController.d.ts +25 -25
  124. package/dist/types/DataChannel/DataChannelLatencyTestResults.d.ts +46 -46
  125. package/dist/types/DataChannel/DataChannelSender.d.ts +21 -21
  126. package/dist/types/DataChannel/InitialSettings.d.ts +44 -44
  127. package/dist/types/DataChannel/LatencyTestResults.d.ts +31 -31
  128. package/dist/types/FreezeFrame/FreezeFrame.d.ts +36 -36
  129. package/dist/types/FreezeFrame/FreezeFrameController.d.ts +37 -37
  130. package/dist/types/Inputs/GamepadController.d.ts +61 -61
  131. package/dist/types/Inputs/GamepadTypes.d.ts +15 -15
  132. package/dist/types/Inputs/IInputController.d.ts +16 -16
  133. package/dist/types/Inputs/InputClassesFactory.d.ts +53 -53
  134. package/dist/types/Inputs/KeyCodes.d.ts +5 -5
  135. package/dist/types/Inputs/KeyboardController.d.ts +34 -34
  136. package/dist/types/Inputs/MouseButtons.d.ts +22 -22
  137. package/dist/types/Inputs/MouseController.d.ts +40 -40
  138. package/dist/types/Inputs/MouseControllerHovering.d.ts +26 -26
  139. package/dist/types/Inputs/MouseControllerLocked.d.ts +31 -31
  140. package/dist/types/Inputs/SpecialKeyCodes.d.ts +14 -14
  141. package/dist/types/Inputs/TouchController.d.ts +28 -28
  142. package/dist/types/Inputs/TouchControllerFake.d.ts +29 -29
  143. package/dist/types/Inputs/XRGamepadController.d.ts +15 -15
  144. package/dist/types/PeerConnectionController/AggregatedStats.d.ts +82 -82
  145. package/dist/types/PeerConnectionController/CandidatePairStats.d.ts +22 -22
  146. package/dist/types/PeerConnectionController/CandidateStat.d.ts +13 -13
  147. package/dist/types/PeerConnectionController/CodecStats.d.ts +14 -14
  148. package/dist/types/PeerConnectionController/DataChannelStats.d.ts +15 -15
  149. package/dist/types/PeerConnectionController/InboundRTPStats.d.ts +141 -141
  150. package/dist/types/PeerConnectionController/InboundTrackStats.d.ts +32 -32
  151. package/dist/types/PeerConnectionController/OutBoundRTPStats.d.ts +23 -23
  152. package/dist/types/PeerConnectionController/PeerConnectionController.d.ts +143 -143
  153. package/dist/types/PeerConnectionController/SessionStats.d.ts +8 -8
  154. package/dist/types/PeerConnectionController/StreamStats.d.ts +9 -9
  155. package/dist/types/PixelStreaming/PixelStreaming.d.ts +271 -271
  156. package/dist/types/UI/OnScreenKeyboard.d.ts +30 -30
  157. package/dist/types/UeInstanceMessage/ResponseController.d.ts +19 -19
  158. package/dist/types/UeInstanceMessage/SendMessageController.d.ts +18 -18
  159. package/dist/types/UeInstanceMessage/StreamMessageController.d.ts +29 -29
  160. package/dist/types/UeInstanceMessage/ToStreamerMessagesController.d.ts +32 -32
  161. package/dist/types/Util/EventEmitter.d.ts +429 -429
  162. package/dist/types/Util/FileUtil.d.ts +32 -32
  163. package/dist/types/Util/IURLSearchParams.d.ts +9 -9
  164. package/dist/types/Util/InputCoordTranslator.d.ts +29 -29
  165. package/dist/types/Util/RTCUtils.d.ts +8 -8
  166. package/dist/types/VideoPlayer/StreamController.d.ts +22 -22
  167. package/dist/types/VideoPlayer/VideoPlayer.d.ts +78 -78
  168. package/dist/types/WebRtcPlayer/WebRtcPlayerController.d.ts +379 -379
  169. package/dist/types/WebXR/WebXRController.d.ts +42 -42
  170. package/dist/types/pixelstreamingfrontend.d.ts +23 -23
  171. package/package.json +45 -45
  172. package/src/Inputs/TouchController.ts +3 -3
@@ -1,65 +1,65 @@
1
- // Copyright Epic Games, Inc. All Rights Reserved.
2
- import { Logger } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
3
- import { XRGamepadController } from '../Inputs/XRGamepadController';
4
- import { XrFrameEvent } from '../Util/EventEmitter';
5
- import { Flags } from '../pixelstreamingfrontend';
6
- export class WebXRController {
7
- constructor(webRtcPlayerController) {
8
- this.xrViewerPose = null;
9
- // Used for comparisons to ensure two numbers are close enough.
10
- this.EPSILON = 0.0000001;
11
- this.videoTexture = null;
12
- this.prevVideoWidth = 0;
13
- this.prevVideoHeight = 0;
14
- this.leftView = null;
15
- this.rightView = null;
16
- // Store the HMD data we have last sent (not all of it is needed every frame unless it changes)
17
- this.lastSentLeftEyeProj = null;
18
- this.lastSentRightEyeProj = null;
19
- this.lastSentRelativeLeftEyePos = null;
20
- this.lastSentRelativeRightEyePos = null;
21
- this.xrSession = null;
22
- this.webRtcController = webRtcPlayerController;
23
- this.xrGamepadController = new XRGamepadController(this.webRtcController.streamMessageController);
24
- this.onSessionEnded = new EventTarget();
25
- this.onSessionStarted = new EventTarget();
26
- this.onFrame = new EventTarget();
27
- }
28
- xrClicked() {
29
- if (!this.xrSession) {
30
- if (!navigator.xr) {
31
- Logger.Error('This browser does not support XR.');
32
- return;
33
- }
34
- navigator.xr
35
- /* Request immersive-vr session without any optional features. */
36
- .requestSession('immersive-vr', { optionalFeatures: [] })
37
- .then((session) => {
38
- this.onXrSessionStarted(session);
39
- });
40
- }
41
- else {
42
- this.xrSession.end();
43
- }
44
- }
45
- onXrSessionEnded() {
46
- Logger.Info('XR Session ended');
47
- this.xrSession = null;
48
- this.onSessionEnded.dispatchEvent(new Event('xrSessionEnded'));
49
- }
50
- initGL() {
51
- if (this.gl) {
52
- return;
53
- }
54
- const canvas = document.createElement('canvas');
55
- this.gl = canvas.getContext('webgl2', {
56
- xrCompatible: true
57
- });
58
- // Set our clear color
59
- this.gl.clearColor(0.0, 0.0, 0.0, 1);
60
- }
61
- initShaders() {
62
- // shader source code
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+ import { Logger } from '@epicgames-ps/lib-pixelstreamingcommon-ue5.5';
3
+ import { XRGamepadController } from '../Inputs/XRGamepadController';
4
+ import { XrFrameEvent } from '../Util/EventEmitter';
5
+ import { Flags } from '../pixelstreamingfrontend';
6
+ export class WebXRController {
7
+ constructor(webRtcPlayerController) {
8
+ this.xrViewerPose = null;
9
+ // Used for comparisons to ensure two numbers are close enough.
10
+ this.EPSILON = 0.0000001;
11
+ this.videoTexture = null;
12
+ this.prevVideoWidth = 0;
13
+ this.prevVideoHeight = 0;
14
+ this.leftView = null;
15
+ this.rightView = null;
16
+ // Store the HMD data we have last sent (not all of it is needed every frame unless it changes)
17
+ this.lastSentLeftEyeProj = null;
18
+ this.lastSentRightEyeProj = null;
19
+ this.lastSentRelativeLeftEyePos = null;
20
+ this.lastSentRelativeRightEyePos = null;
21
+ this.xrSession = null;
22
+ this.webRtcController = webRtcPlayerController;
23
+ this.xrGamepadController = new XRGamepadController(this.webRtcController.streamMessageController);
24
+ this.onSessionEnded = new EventTarget();
25
+ this.onSessionStarted = new EventTarget();
26
+ this.onFrame = new EventTarget();
27
+ }
28
+ xrClicked() {
29
+ if (!this.xrSession) {
30
+ if (!navigator.xr) {
31
+ Logger.Error('This browser does not support XR.');
32
+ return;
33
+ }
34
+ navigator.xr
35
+ /* Request immersive-vr session without any optional features. */
36
+ .requestSession('immersive-vr', { optionalFeatures: [] })
37
+ .then((session) => {
38
+ this.onXrSessionStarted(session);
39
+ });
40
+ }
41
+ else {
42
+ this.xrSession.end();
43
+ }
44
+ }
45
+ onXrSessionEnded() {
46
+ Logger.Info('XR Session ended');
47
+ this.xrSession = null;
48
+ this.onSessionEnded.dispatchEvent(new Event('xrSessionEnded'));
49
+ }
50
+ initGL() {
51
+ if (this.gl) {
52
+ return;
53
+ }
54
+ const canvas = document.createElement('canvas');
55
+ this.gl = canvas.getContext('webgl2', {
56
+ xrCompatible: true
57
+ });
58
+ // Set our clear color
59
+ this.gl.clearColor(0.0, 0.0, 0.0, 1);
60
+ }
61
+ initShaders() {
62
+ // shader source code
63
63
  const vertexShaderSource = `
64
64
  attribute vec2 a_position;
65
65
  attribute vec2 a_texCoord;
@@ -73,7 +73,7 @@ export class WebXRController {
73
73
  // The GPU will interpolate this value between points.
74
74
  v_texCoord = a_texCoord;
75
75
  }
76
- `;
76
+ `;
77
77
  const fragmentShaderSource = `
78
78
  precision mediump float;
79
79
 
@@ -86,272 +86,272 @@ export class WebXRController {
86
86
  void main() {
87
87
  gl_FragColor = texture2D(u_image, v_texCoord);
88
88
  }
89
- `;
90
- // setup vertex shader
91
- const vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
92
- this.gl.shaderSource(vertexShader, vertexShaderSource);
93
- this.gl.compileShader(vertexShader);
94
- // setup fragment shader
95
- const fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
96
- this.gl.shaderSource(fragmentShader, fragmentShaderSource);
97
- this.gl.compileShader(fragmentShader);
98
- // setup GLSL program
99
- const shaderProgram = this.gl.createProgram();
100
- this.gl.attachShader(shaderProgram, vertexShader);
101
- this.gl.attachShader(shaderProgram, fragmentShader);
102
- this.gl.linkProgram(shaderProgram);
103
- this.gl.useProgram(shaderProgram);
104
- // look up where vertex data needs to go
105
- this.positionLocation = this.gl.getAttribLocation(shaderProgram, 'a_position');
106
- this.texcoordLocation = this.gl.getAttribLocation(shaderProgram, 'a_texCoord');
107
- }
108
- updateVideoTexture() {
109
- if (!this.videoTexture) {
110
- // Create our texture that we use in our shader
111
- // and bind it once because we never use any other texture.
112
- this.videoTexture = this.gl.createTexture();
113
- this.gl.bindTexture(this.gl.TEXTURE_2D, this.videoTexture);
114
- // Set the parameters so we can render any size image.
115
- this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
116
- this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
117
- this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
118
- this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
119
- }
120
- const videoHeight = this.webRtcController.videoPlayer.getVideoElement().videoHeight;
121
- const videoWidth = this.webRtcController.videoPlayer.getVideoElement().videoWidth;
122
- if (this.prevVideoHeight != videoHeight || this.prevVideoWidth != videoWidth) {
123
- // Do full update of texture if dimensions do not match
124
- this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, videoWidth, videoHeight, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.webRtcController.videoPlayer.getVideoElement());
125
- }
126
- else {
127
- // If dimensions match just update the sub region
128
- this.gl.texSubImage2D(this.gl.TEXTURE_2D, 0, 0, 0, videoWidth, videoHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.webRtcController.videoPlayer.getVideoElement());
129
- }
130
- // Update prev video width/height
131
- this.prevVideoHeight = videoHeight;
132
- this.prevVideoWidth = videoWidth;
133
- }
134
- initBuffers() {
135
- // Create out position buffer and its vertex shader attribute
136
- {
137
- // Create a buffer to put the the vertices of the plane we will draw the video stream onto
138
- this.positionBuffer = this.gl.createBuffer();
139
- // Bind the position buffer
140
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
141
- // Enable `positionLocation` to be used as vertex shader attribute
142
- this.gl.enableVertexAttribArray(this.positionLocation);
143
- // Note: positions are passed in clip-space coordinates [-1..1] so no need to convert in-shader
144
- // prettier-ignore
145
- this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([
146
- -1.0, 1.0,
147
- 1.0, 1.0,
148
- -1.0, -1.0,
149
- -1.0, -1.0,
150
- 1.0, 1.0,
151
- 1.0, -1.0
152
- ]), this.gl.STATIC_DRAW);
153
- // Tell position attribute of the vertex shader how to get data out of the bound buffer (the positionBuffer)
154
- this.gl.vertexAttribPointer(this.positionLocation, 2 /*size*/, this.gl.FLOAT /*type*/, false /*normalize*/, 0 /*stride*/, 0 /*offset*/);
155
- }
156
- // Create our texture coordinate buffers for accessing our texture
157
- {
158
- this.texcoordBuffer = this.gl.createBuffer();
159
- // Bind the texture coordinate buffer
160
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texcoordBuffer);
161
- // Enable `texcoordLocation` to be used as a vertex shader attribute
162
- this.gl.enableVertexAttribArray(this.texcoordLocation);
163
- // The texture coordinates to apply for rectangle we are drawing
164
- this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0]), this.gl.STATIC_DRAW);
165
- // Tell texture coordinate attribute of the vertex shader how to get data out of the bound buffer (the texcoordBuffer)
166
- this.gl.vertexAttribPointer(this.texcoordLocation, 2 /*size*/, this.gl.FLOAT /*type*/, false /*normalize*/, 0 /*stride*/, 0 /*offset*/);
167
- }
168
- }
169
- onXrSessionStarted(session) {
170
- Logger.Info('XR Session started');
171
- this.xrSession = session;
172
- this.xrSession.addEventListener('end', () => {
173
- this.onXrSessionEnded();
174
- });
175
- // Initialization
176
- this.initGL();
177
- this.initShaders();
178
- this.initBuffers();
179
- session.requestReferenceSpace('local').then((refSpace) => {
180
- this.xrRefSpace = refSpace;
181
- // Set up our base layer (i.e. a projection layer that fills the entire XR viewport).
182
- this.xrSession.updateRenderState({
183
- baseLayer: new XRWebGLLayer(this.xrSession, this.gl)
184
- });
185
- // Update target framerate to 90 fps if 90 fps is supported in this XR device
186
- if (this.xrSession.supportedFrameRates) {
187
- for (const frameRate of this.xrSession.supportedFrameRates) {
188
- if (frameRate == 90) {
189
- session.updateTargetFrameRate(90);
190
- }
191
- }
192
- }
193
- // Binding to each new frame to get latest XR updates
194
- this.xrSession.requestAnimationFrame(this.onXrFrame.bind(this));
195
- });
196
- this.onSessionStarted.dispatchEvent(new Event('xrSessionStarted'));
197
- }
198
- areArraysEqual(a, b) {
199
- return (a.length === b.length && a.every((element, index) => Math.abs(element - b[index]) <= this.EPSILON));
200
- }
201
- arePointsEqual(a, b) {
202
- return (Math.abs(a.x - b.x) >= this.EPSILON &&
203
- Math.abs(a.y - b.y) >= this.EPSILON &&
204
- Math.abs(a.z - b.z) >= this.EPSILON);
205
- }
206
- sendXRDataToUE() {
207
- if (this.leftView == null || this.rightView == null) {
208
- return;
209
- }
210
- // We selectively send either the `XREyeViews` or `XRHMDTransform`
211
- // messages over the datachannel. The reason for this selective sending is that
212
- // the `XREyeViews` is a much larger message and changes infrequently (e.g. only when user changes headset IPD).
213
- // Therefore, we only need to send it once on startup and then any time it changes.
214
- // The rest of the time we can send the `XRHMDTransform` message.
215
- let shouldSendEyeViews = this.lastSentLeftEyeProj == null ||
216
- this.lastSentRightEyeProj == null ||
217
- this.lastSentRelativeLeftEyePos == null ||
218
- this.lastSentRelativeRightEyePos == null;
219
- const leftEyeTrans = this.leftView.transform.matrix;
220
- const leftEyeProj = this.leftView.projectionMatrix;
221
- const rightEyeTrans = this.rightView.transform.matrix;
222
- const rightEyeProj = this.rightView.projectionMatrix;
223
- const hmdTrans = this.xrViewerPose.transform.matrix;
224
- // Check if projection matrices have changed
225
- if (!shouldSendEyeViews && this.lastSentLeftEyeProj != null && this.lastSentRightEyeProj != null) {
226
- const leftEyeProjUnchanged = this.areArraysEqual(leftEyeProj, this.lastSentLeftEyeProj);
227
- const rightEyeProjUnchanged = this.areArraysEqual(rightEyeProj, this.lastSentRightEyeProj);
228
- shouldSendEyeViews = leftEyeProjUnchanged == false || rightEyeProjUnchanged == false;
229
- }
230
- const leftEyeRelativePos = new DOMPointReadOnly(this.leftView.transform.position.x - this.xrViewerPose.transform.position.x, this.leftView.transform.position.y - this.xrViewerPose.transform.position.y, this.leftView.transform.position.z - this.xrViewerPose.transform.position.z, 1.0);
231
- const rightEyeRelativePos = new DOMPointReadOnly(this.leftView.transform.position.x - this.xrViewerPose.transform.position.x, this.leftView.transform.position.y - this.xrViewerPose.transform.position.y, this.leftView.transform.position.z - this.xrViewerPose.transform.position.z, 1.0);
232
- // Check if relative eye pos has changed (e.g IPD changed)
233
- if (!shouldSendEyeViews &&
234
- this.lastSentRelativeLeftEyePos != null &&
235
- this.lastSentRelativeRightEyePos != null) {
236
- const leftEyePosUnchanged = this.arePointsEqual(leftEyeRelativePos, this.lastSentRelativeLeftEyePos);
237
- const rightEyePosUnchanged = this.arePointsEqual(rightEyeRelativePos, this.lastSentRelativeRightEyePos);
238
- shouldSendEyeViews = leftEyePosUnchanged == false || rightEyePosUnchanged == false;
239
- // Note: We are not checking if EyeView rotation changes (as far as I know no HMD supports changing this value at runtime).
240
- }
241
- if (shouldSendEyeViews) {
242
- // send transform (4x4) and projection matrix (4x4) data for each eye (left first, then right)
243
- // prettier-ignore
244
- this.webRtcController.streamMessageController.toStreamerHandlers.get('XREyeViews')([
245
- // Left eye 4x4 transform matrix
246
- leftEyeTrans[0], leftEyeTrans[4], leftEyeTrans[8], leftEyeTrans[12],
247
- leftEyeTrans[1], leftEyeTrans[5], leftEyeTrans[9], leftEyeTrans[13],
248
- leftEyeTrans[2], leftEyeTrans[6], leftEyeTrans[10], leftEyeTrans[14],
249
- leftEyeTrans[3], leftEyeTrans[7], leftEyeTrans[11], leftEyeTrans[15],
250
- // Left eye 4x4 projection matrix
251
- leftEyeProj[0], leftEyeProj[4], leftEyeProj[8], leftEyeProj[12],
252
- leftEyeProj[1], leftEyeProj[5], leftEyeProj[9], leftEyeProj[13],
253
- leftEyeProj[2], leftEyeProj[6], leftEyeProj[10], leftEyeProj[14],
254
- leftEyeProj[3], leftEyeProj[7], leftEyeProj[11], leftEyeProj[15],
255
- // Right eye 4x4 transform matrix
256
- rightEyeTrans[0], rightEyeTrans[4], rightEyeTrans[8], rightEyeTrans[12],
257
- rightEyeTrans[1], rightEyeTrans[5], rightEyeTrans[9], rightEyeTrans[13],
258
- rightEyeTrans[2], rightEyeTrans[6], rightEyeTrans[10], rightEyeTrans[14],
259
- rightEyeTrans[3], rightEyeTrans[7], rightEyeTrans[11], rightEyeTrans[15],
260
- // right eye 4x4 projection matrix
261
- rightEyeProj[0], rightEyeProj[4], rightEyeProj[8], rightEyeProj[12],
262
- rightEyeProj[1], rightEyeProj[5], rightEyeProj[9], rightEyeProj[13],
263
- rightEyeProj[2], rightEyeProj[6], rightEyeProj[10], rightEyeProj[14],
264
- rightEyeProj[3], rightEyeProj[7], rightEyeProj[11], rightEyeProj[15],
265
- // HMD 4x4 transform
266
- hmdTrans[0], hmdTrans[4], hmdTrans[8], hmdTrans[12],
267
- hmdTrans[1], hmdTrans[5], hmdTrans[9], hmdTrans[13],
268
- hmdTrans[2], hmdTrans[6], hmdTrans[10], hmdTrans[14],
269
- hmdTrans[3], hmdTrans[7], hmdTrans[11], hmdTrans[15],
270
- ]);
271
- this.lastSentLeftEyeProj = leftEyeProj;
272
- this.lastSentRightEyeProj = rightEyeProj;
273
- this.lastSentRelativeLeftEyePos = leftEyeRelativePos;
274
- this.lastSentRelativeRightEyePos = rightEyeRelativePos;
275
- }
276
- else {
277
- // If we don't need to the entire eye views being sent just send the HMD transform
278
- this.webRtcController.streamMessageController.toStreamerHandlers.get('XRHMDTransform')([
279
- // HMD 4x4 transform
280
- hmdTrans[0],
281
- hmdTrans[4],
282
- hmdTrans[8],
283
- hmdTrans[12],
284
- hmdTrans[1],
285
- hmdTrans[5],
286
- hmdTrans[9],
287
- hmdTrans[13],
288
- hmdTrans[2],
289
- hmdTrans[6],
290
- hmdTrans[10],
291
- hmdTrans[14],
292
- hmdTrans[3],
293
- hmdTrans[7],
294
- hmdTrans[11],
295
- hmdTrans[15]
296
- ]);
297
- }
298
- }
299
- onXrFrame(time, frame) {
300
- this.xrViewerPose = frame.getViewerPose(this.xrRefSpace);
301
- if (this.xrViewerPose) {
302
- this.updateViews();
303
- if (this.leftView == null || this.rightView == null) {
304
- return;
305
- }
306
- this.sendXRDataToUE();
307
- this.updateVideoTexture();
308
- this.render();
309
- }
310
- if (this.webRtcController.config.isFlagEnabled(Flags.XRControllerInput)) {
311
- this.xrSession.inputSources.forEach((source, _index, _array) => {
312
- this.xrGamepadController.updateStatus(source, frame, this.xrRefSpace);
313
- }, this);
314
- }
315
- this.xrSession.requestAnimationFrame((time, frame) => this.onXrFrame(time, frame));
316
- this.onFrame.dispatchEvent(new XrFrameEvent({ time, frame }));
317
- }
318
- updateViews() {
319
- if (!this.xrViewerPose) {
320
- return;
321
- }
322
- for (const view of this.xrViewerPose.views) {
323
- if (view.eye === 'left') {
324
- this.leftView = view;
325
- }
326
- else if (view.eye === 'right') {
327
- this.rightView = view;
328
- }
329
- }
330
- }
331
- render() {
332
- if (!this.gl) {
333
- return;
334
- }
335
- // Bind the framebuffer to the base layer's framebuffer
336
- const glLayer = this.xrSession.renderState.baseLayer;
337
- this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, glLayer.framebuffer);
338
- // Set the relevant portion of clip space
339
- this.gl.viewport(0, 0, glLayer.framebufferWidth, glLayer.framebufferHeight);
340
- // Draw the rectangle we will show the video stream texture on
341
- this.gl.drawArrays(this.gl.TRIANGLES /*primitiveType*/, 0 /*offset*/, 6 /*count*/);
342
- }
343
- static isSessionSupported(mode) {
344
- if (location.protocol !== 'https:') {
345
- Logger.Info('WebXR requires https, if you want WebXR use https.');
346
- }
347
- if (navigator.xr) {
348
- return navigator.xr.isSessionSupported(mode);
349
- }
350
- else {
351
- return new Promise(() => {
352
- return false;
353
- });
354
- }
355
- }
356
- }
89
+ `;
90
+ // setup vertex shader
91
+ const vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
92
+ this.gl.shaderSource(vertexShader, vertexShaderSource);
93
+ this.gl.compileShader(vertexShader);
94
+ // setup fragment shader
95
+ const fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
96
+ this.gl.shaderSource(fragmentShader, fragmentShaderSource);
97
+ this.gl.compileShader(fragmentShader);
98
+ // setup GLSL program
99
+ const shaderProgram = this.gl.createProgram();
100
+ this.gl.attachShader(shaderProgram, vertexShader);
101
+ this.gl.attachShader(shaderProgram, fragmentShader);
102
+ this.gl.linkProgram(shaderProgram);
103
+ this.gl.useProgram(shaderProgram);
104
+ // look up where vertex data needs to go
105
+ this.positionLocation = this.gl.getAttribLocation(shaderProgram, 'a_position');
106
+ this.texcoordLocation = this.gl.getAttribLocation(shaderProgram, 'a_texCoord');
107
+ }
108
+ updateVideoTexture() {
109
+ if (!this.videoTexture) {
110
+ // Create our texture that we use in our shader
111
+ // and bind it once because we never use any other texture.
112
+ this.videoTexture = this.gl.createTexture();
113
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this.videoTexture);
114
+ // Set the parameters so we can render any size image.
115
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
116
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
117
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
118
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
119
+ }
120
+ const videoHeight = this.webRtcController.videoPlayer.getVideoElement().videoHeight;
121
+ const videoWidth = this.webRtcController.videoPlayer.getVideoElement().videoWidth;
122
+ if (this.prevVideoHeight != videoHeight || this.prevVideoWidth != videoWidth) {
123
+ // Do full update of texture if dimensions do not match
124
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, videoWidth, videoHeight, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.webRtcController.videoPlayer.getVideoElement());
125
+ }
126
+ else {
127
+ // If dimensions match just update the sub region
128
+ this.gl.texSubImage2D(this.gl.TEXTURE_2D, 0, 0, 0, videoWidth, videoHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.webRtcController.videoPlayer.getVideoElement());
129
+ }
130
+ // Update prev video width/height
131
+ this.prevVideoHeight = videoHeight;
132
+ this.prevVideoWidth = videoWidth;
133
+ }
134
+ initBuffers() {
135
+ // Create out position buffer and its vertex shader attribute
136
+ {
137
+ // Create a buffer to put the the vertices of the plane we will draw the video stream onto
138
+ this.positionBuffer = this.gl.createBuffer();
139
+ // Bind the position buffer
140
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
141
+ // Enable `positionLocation` to be used as vertex shader attribute
142
+ this.gl.enableVertexAttribArray(this.positionLocation);
143
+ // Note: positions are passed in clip-space coordinates [-1..1] so no need to convert in-shader
144
+ // prettier-ignore
145
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([
146
+ -1.0, 1.0,
147
+ 1.0, 1.0,
148
+ -1.0, -1.0,
149
+ -1.0, -1.0,
150
+ 1.0, 1.0,
151
+ 1.0, -1.0
152
+ ]), this.gl.STATIC_DRAW);
153
+ // Tell position attribute of the vertex shader how to get data out of the bound buffer (the positionBuffer)
154
+ this.gl.vertexAttribPointer(this.positionLocation, 2 /*size*/, this.gl.FLOAT /*type*/, false /*normalize*/, 0 /*stride*/, 0 /*offset*/);
155
+ }
156
+ // Create our texture coordinate buffers for accessing our texture
157
+ {
158
+ this.texcoordBuffer = this.gl.createBuffer();
159
+ // Bind the texture coordinate buffer
160
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texcoordBuffer);
161
+ // Enable `texcoordLocation` to be used as a vertex shader attribute
162
+ this.gl.enableVertexAttribArray(this.texcoordLocation);
163
+ // The texture coordinates to apply for rectangle we are drawing
164
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0]), this.gl.STATIC_DRAW);
165
+ // Tell texture coordinate attribute of the vertex shader how to get data out of the bound buffer (the texcoordBuffer)
166
+ this.gl.vertexAttribPointer(this.texcoordLocation, 2 /*size*/, this.gl.FLOAT /*type*/, false /*normalize*/, 0 /*stride*/, 0 /*offset*/);
167
+ }
168
+ }
169
+ onXrSessionStarted(session) {
170
+ Logger.Info('XR Session started');
171
+ this.xrSession = session;
172
+ this.xrSession.addEventListener('end', () => {
173
+ this.onXrSessionEnded();
174
+ });
175
+ // Initialization
176
+ this.initGL();
177
+ this.initShaders();
178
+ this.initBuffers();
179
+ session.requestReferenceSpace('local').then((refSpace) => {
180
+ this.xrRefSpace = refSpace;
181
+ // Set up our base layer (i.e. a projection layer that fills the entire XR viewport).
182
+ this.xrSession.updateRenderState({
183
+ baseLayer: new XRWebGLLayer(this.xrSession, this.gl)
184
+ });
185
+ // Update target framerate to 90 fps if 90 fps is supported in this XR device
186
+ if (this.xrSession.supportedFrameRates) {
187
+ for (const frameRate of this.xrSession.supportedFrameRates) {
188
+ if (frameRate == 90) {
189
+ session.updateTargetFrameRate(90);
190
+ }
191
+ }
192
+ }
193
+ // Binding to each new frame to get latest XR updates
194
+ this.xrSession.requestAnimationFrame(this.onXrFrame.bind(this));
195
+ });
196
+ this.onSessionStarted.dispatchEvent(new Event('xrSessionStarted'));
197
+ }
198
+ areArraysEqual(a, b) {
199
+ return (a.length === b.length && a.every((element, index) => Math.abs(element - b[index]) <= this.EPSILON));
200
+ }
201
+ arePointsEqual(a, b) {
202
+ return (Math.abs(a.x - b.x) >= this.EPSILON &&
203
+ Math.abs(a.y - b.y) >= this.EPSILON &&
204
+ Math.abs(a.z - b.z) >= this.EPSILON);
205
+ }
206
+ sendXRDataToUE() {
207
+ if (this.leftView == null || this.rightView == null) {
208
+ return;
209
+ }
210
+ // We selectively send either the `XREyeViews` or `XRHMDTransform`
211
+ // messages over the datachannel. The reason for this selective sending is that
212
+ // the `XREyeViews` is a much larger message and changes infrequently (e.g. only when user changes headset IPD).
213
+ // Therefore, we only need to send it once on startup and then any time it changes.
214
+ // The rest of the time we can send the `XRHMDTransform` message.
215
+ let shouldSendEyeViews = this.lastSentLeftEyeProj == null ||
216
+ this.lastSentRightEyeProj == null ||
217
+ this.lastSentRelativeLeftEyePos == null ||
218
+ this.lastSentRelativeRightEyePos == null;
219
+ const leftEyeTrans = this.leftView.transform.matrix;
220
+ const leftEyeProj = this.leftView.projectionMatrix;
221
+ const rightEyeTrans = this.rightView.transform.matrix;
222
+ const rightEyeProj = this.rightView.projectionMatrix;
223
+ const hmdTrans = this.xrViewerPose.transform.matrix;
224
+ // Check if projection matrices have changed
225
+ if (!shouldSendEyeViews && this.lastSentLeftEyeProj != null && this.lastSentRightEyeProj != null) {
226
+ const leftEyeProjUnchanged = this.areArraysEqual(leftEyeProj, this.lastSentLeftEyeProj);
227
+ const rightEyeProjUnchanged = this.areArraysEqual(rightEyeProj, this.lastSentRightEyeProj);
228
+ shouldSendEyeViews = leftEyeProjUnchanged == false || rightEyeProjUnchanged == false;
229
+ }
230
+ const leftEyeRelativePos = new DOMPointReadOnly(this.leftView.transform.position.x - this.xrViewerPose.transform.position.x, this.leftView.transform.position.y - this.xrViewerPose.transform.position.y, this.leftView.transform.position.z - this.xrViewerPose.transform.position.z, 1.0);
231
+ const rightEyeRelativePos = new DOMPointReadOnly(this.leftView.transform.position.x - this.xrViewerPose.transform.position.x, this.leftView.transform.position.y - this.xrViewerPose.transform.position.y, this.leftView.transform.position.z - this.xrViewerPose.transform.position.z, 1.0);
232
+ // Check if relative eye pos has changed (e.g IPD changed)
233
+ if (!shouldSendEyeViews &&
234
+ this.lastSentRelativeLeftEyePos != null &&
235
+ this.lastSentRelativeRightEyePos != null) {
236
+ const leftEyePosUnchanged = this.arePointsEqual(leftEyeRelativePos, this.lastSentRelativeLeftEyePos);
237
+ const rightEyePosUnchanged = this.arePointsEqual(rightEyeRelativePos, this.lastSentRelativeRightEyePos);
238
+ shouldSendEyeViews = leftEyePosUnchanged == false || rightEyePosUnchanged == false;
239
+ // Note: We are not checking if EyeView rotation changes (as far as I know no HMD supports changing this value at runtime).
240
+ }
241
+ if (shouldSendEyeViews) {
242
+ // send transform (4x4) and projection matrix (4x4) data for each eye (left first, then right)
243
+ // prettier-ignore
244
+ this.webRtcController.streamMessageController.toStreamerHandlers.get('XREyeViews')([
245
+ // Left eye 4x4 transform matrix
246
+ leftEyeTrans[0], leftEyeTrans[4], leftEyeTrans[8], leftEyeTrans[12],
247
+ leftEyeTrans[1], leftEyeTrans[5], leftEyeTrans[9], leftEyeTrans[13],
248
+ leftEyeTrans[2], leftEyeTrans[6], leftEyeTrans[10], leftEyeTrans[14],
249
+ leftEyeTrans[3], leftEyeTrans[7], leftEyeTrans[11], leftEyeTrans[15],
250
+ // Left eye 4x4 projection matrix
251
+ leftEyeProj[0], leftEyeProj[4], leftEyeProj[8], leftEyeProj[12],
252
+ leftEyeProj[1], leftEyeProj[5], leftEyeProj[9], leftEyeProj[13],
253
+ leftEyeProj[2], leftEyeProj[6], leftEyeProj[10], leftEyeProj[14],
254
+ leftEyeProj[3], leftEyeProj[7], leftEyeProj[11], leftEyeProj[15],
255
+ // Right eye 4x4 transform matrix
256
+ rightEyeTrans[0], rightEyeTrans[4], rightEyeTrans[8], rightEyeTrans[12],
257
+ rightEyeTrans[1], rightEyeTrans[5], rightEyeTrans[9], rightEyeTrans[13],
258
+ rightEyeTrans[2], rightEyeTrans[6], rightEyeTrans[10], rightEyeTrans[14],
259
+ rightEyeTrans[3], rightEyeTrans[7], rightEyeTrans[11], rightEyeTrans[15],
260
+ // right eye 4x4 projection matrix
261
+ rightEyeProj[0], rightEyeProj[4], rightEyeProj[8], rightEyeProj[12],
262
+ rightEyeProj[1], rightEyeProj[5], rightEyeProj[9], rightEyeProj[13],
263
+ rightEyeProj[2], rightEyeProj[6], rightEyeProj[10], rightEyeProj[14],
264
+ rightEyeProj[3], rightEyeProj[7], rightEyeProj[11], rightEyeProj[15],
265
+ // HMD 4x4 transform
266
+ hmdTrans[0], hmdTrans[4], hmdTrans[8], hmdTrans[12],
267
+ hmdTrans[1], hmdTrans[5], hmdTrans[9], hmdTrans[13],
268
+ hmdTrans[2], hmdTrans[6], hmdTrans[10], hmdTrans[14],
269
+ hmdTrans[3], hmdTrans[7], hmdTrans[11], hmdTrans[15],
270
+ ]);
271
+ this.lastSentLeftEyeProj = leftEyeProj;
272
+ this.lastSentRightEyeProj = rightEyeProj;
273
+ this.lastSentRelativeLeftEyePos = leftEyeRelativePos;
274
+ this.lastSentRelativeRightEyePos = rightEyeRelativePos;
275
+ }
276
+ else {
277
+ // If we don't need to the entire eye views being sent just send the HMD transform
278
+ this.webRtcController.streamMessageController.toStreamerHandlers.get('XRHMDTransform')([
279
+ // HMD 4x4 transform
280
+ hmdTrans[0],
281
+ hmdTrans[4],
282
+ hmdTrans[8],
283
+ hmdTrans[12],
284
+ hmdTrans[1],
285
+ hmdTrans[5],
286
+ hmdTrans[9],
287
+ hmdTrans[13],
288
+ hmdTrans[2],
289
+ hmdTrans[6],
290
+ hmdTrans[10],
291
+ hmdTrans[14],
292
+ hmdTrans[3],
293
+ hmdTrans[7],
294
+ hmdTrans[11],
295
+ hmdTrans[15]
296
+ ]);
297
+ }
298
+ }
299
+ onXrFrame(time, frame) {
300
+ this.xrViewerPose = frame.getViewerPose(this.xrRefSpace);
301
+ if (this.xrViewerPose) {
302
+ this.updateViews();
303
+ if (this.leftView == null || this.rightView == null) {
304
+ return;
305
+ }
306
+ this.sendXRDataToUE();
307
+ this.updateVideoTexture();
308
+ this.render();
309
+ }
310
+ if (this.webRtcController.config.isFlagEnabled(Flags.XRControllerInput)) {
311
+ this.xrSession.inputSources.forEach((source, _index, _array) => {
312
+ this.xrGamepadController.updateStatus(source, frame, this.xrRefSpace);
313
+ }, this);
314
+ }
315
+ this.xrSession.requestAnimationFrame((time, frame) => this.onXrFrame(time, frame));
316
+ this.onFrame.dispatchEvent(new XrFrameEvent({ time, frame }));
317
+ }
318
+ updateViews() {
319
+ if (!this.xrViewerPose) {
320
+ return;
321
+ }
322
+ for (const view of this.xrViewerPose.views) {
323
+ if (view.eye === 'left') {
324
+ this.leftView = view;
325
+ }
326
+ else if (view.eye === 'right') {
327
+ this.rightView = view;
328
+ }
329
+ }
330
+ }
331
+ render() {
332
+ if (!this.gl) {
333
+ return;
334
+ }
335
+ // Bind the framebuffer to the base layer's framebuffer
336
+ const glLayer = this.xrSession.renderState.baseLayer;
337
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, glLayer.framebuffer);
338
+ // Set the relevant portion of clip space
339
+ this.gl.viewport(0, 0, glLayer.framebufferWidth, glLayer.framebufferHeight);
340
+ // Draw the rectangle we will show the video stream texture on
341
+ this.gl.drawArrays(this.gl.TRIANGLES /*primitiveType*/, 0 /*offset*/, 6 /*count*/);
342
+ }
343
+ static isSessionSupported(mode) {
344
+ if (location.protocol !== 'https:') {
345
+ Logger.Info('WebXR requires https, if you want WebXR use https.');
346
+ }
347
+ if (navigator.xr) {
348
+ return navigator.xr.isSessionSupported(mode);
349
+ }
350
+ else {
351
+ return new Promise(() => {
352
+ return false;
353
+ });
354
+ }
355
+ }
356
+ }
357
357
  //# sourceMappingURL=WebXRController.js.map