xrblocks 0.3.1 → 0.4.0

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.
@@ -26,6 +26,7 @@ export declare class GeminiManager extends xb.Script<GeminiManagerEventMap> {
26
26
  currentInputText: string;
27
27
  currentOutputText: string;
28
28
  tools: xb.Tool[];
29
+ scheduleAheadTime: number;
29
30
  constructor();
30
31
  init(): void;
31
32
  startGeminiLive({ liveParams, model, }?: {
@@ -1,6 +1,7 @@
1
1
  import * as xb from 'xrblocks';
2
2
  import { AUDIO_CAPTURE_PROCESSOR_CODE } from './AudioCaptureProcessorCode.js';
3
3
 
4
+ const DEFAULT_SCHEDULE_AHEAD_TIME = 1.0;
4
5
  class GeminiManager extends xb.Script {
5
6
  constructor() {
6
7
  super();
@@ -19,6 +20,7 @@ class GeminiManager extends xb.Script {
19
20
  this.currentInputText = '';
20
21
  this.currentOutputText = '';
21
22
  this.tools = [];
23
+ this.scheduleAheadTime = DEFAULT_SCHEDULE_AHEAD_TIME;
22
24
  }
23
25
  init() {
24
26
  this.xrDeviceCamera = xb.core.deviceCamera;
@@ -191,10 +193,9 @@ class GeminiManager extends xb.Script {
191
193
  }
192
194
  }
193
195
  scheduleAudioBuffers() {
194
- const SCHEDULE_AHEAD_TIME = 0.2;
195
196
  while (this.audioQueue.length > 0 &&
196
197
  this.nextAudioStartTime <=
197
- this.audioContext.currentTime + SCHEDULE_AHEAD_TIME) {
198
+ this.audioContext.currentTime + this.scheduleAheadTime) {
198
199
  const audioBuffer = this.audioQueue.shift();
199
200
  const source = this.audioContext.createBufferSource();
200
201
  source.buffer = audioBuffer;
@@ -95,6 +95,7 @@ export declare class Options {
95
95
  * Whether to use post-processing effects.
96
96
  */
97
97
  usePostprocessing: boolean;
98
+ enableSimulator: boolean;
98
99
  /**
99
100
  * Configuration for the XR session button.
100
101
  */
@@ -104,7 +105,7 @@ export declare class Options {
104
105
  endText: string;
105
106
  invalidText: string;
106
107
  startSimulatorText: string;
107
- enableSimulator: boolean;
108
+ showEnterSimulatorButton: boolean;
108
109
  alwaysAutostartSimulator: boolean;
109
110
  };
110
111
  /**
@@ -34,6 +34,7 @@ export declare class WebXRSessionManager extends THREE.EventDispatcher<WebXRSess
34
34
  private sessionOptions?;
35
35
  private onSessionEndedBound;
36
36
  private xrModeSupported?;
37
+ private waitingForXRSession;
37
38
  constructor(renderer: THREE.WebGLRenderer, sessionInit: XRSessionInit, mode: XRSessionMode);
38
39
  /**
39
40
  * Checks for WebXR support and availability of the requested session mode.
@@ -9,7 +9,7 @@ export declare class XRButton {
9
9
  domElement: HTMLDivElement;
10
10
  simulatorButtonElement: HTMLButtonElement;
11
11
  xrButtonElement: HTMLButtonElement;
12
- constructor(sessionManager: WebXRSessionManager, startText?: string, endText?: string, invalidText?: string, startSimulatorText?: string, enableSimulator?: boolean, startSimulator?: () => void);
12
+ constructor(sessionManager: WebXRSessionManager, startText?: string, endText?: string, invalidText?: string, startSimulatorText?: string, showEnterSimulatorButton?: boolean, startSimulator?: () => void);
13
13
  private createSimulatorButton;
14
14
  private createXRButtonElement;
15
15
  private onSessionReady;
@@ -14,6 +14,7 @@ export declare class AudioPlayer extends Script {
14
14
  private categoryVolumes?;
15
15
  private volume;
16
16
  private category;
17
+ scheduleAheadTime: number;
17
18
  constructor(options?: AudioPlayerOptions);
18
19
  /**
19
20
  * Sets the CategoryVolumes instance for this player to respect
package/build/xrblocks.js CHANGED
@@ -14,9 +14,9 @@
14
14
  * limitations under the License.
15
15
  *
16
16
  * @file xrblocks.js
17
- * @version v0.3.1
18
- * @commitid 8945d46
19
- * @builddate 2025-11-04T06:32:35.799Z
17
+ * @version v0.4.0
18
+ * @commitid 385db96
19
+ * @builddate 2025-11-20T21:08:04.032Z
20
20
  * @description XR Blocks SDK, built from source with the above commit ID.
21
21
  * @agent When using with Gemini to create XR apps, use **Gemini Canvas** mode,
22
22
  * and follow rules below:
@@ -3208,9 +3208,9 @@ class Depth {
3208
3208
  update(frame) {
3209
3209
  if (!this.options.enabled)
3210
3210
  return;
3211
- if (!frame)
3212
- return;
3213
- this.updateLocalDepth(frame);
3211
+ if (frame) {
3212
+ this.updateLocalDepth(frame);
3213
+ }
3214
3214
  if (this.options.occlusion.enabled) {
3215
3215
  this.renderOcclusionPass();
3216
3216
  }
@@ -4284,6 +4284,7 @@ class WebXRSessionManager extends THREE.EventDispatcher {
4284
4284
  this.sessionInit = sessionInit;
4285
4285
  this.mode = mode;
4286
4286
  this.onSessionEndedBound = this.onSessionEndedInternal.bind(this);
4287
+ this.waitingForXRSession = false;
4287
4288
  }
4288
4289
  /**
4289
4290
  * Checks for WebXR support and availability of the requested session mode.
@@ -4350,8 +4351,15 @@ class WebXRSessionManager extends THREE.EventDispatcher {
4350
4351
  else if (this.currentSession) {
4351
4352
  throw new Error('Session already started');
4352
4353
  }
4354
+ else if (this.waitingForXRSession) {
4355
+ throw new Error('Waiting for session to start');
4356
+ }
4357
+ this.waitingForXRSession = true;
4353
4358
  navigator
4354
4359
  .xr.requestSession(this.mode, this.sessionOptions)
4360
+ .finally(() => {
4361
+ this.waitingForXRSession = false;
4362
+ })
4355
4363
  .then(this.onSessionStartedInternal.bind(this));
4356
4364
  }
4357
4365
  /**
@@ -4394,7 +4402,7 @@ class WebXRSessionManager extends THREE.EventDispatcher {
4394
4402
  const XRBUTTON_WRAPPER_ID = 'XRButtonWrapper';
4395
4403
  const XRBUTTON_CLASS = 'XRButton';
4396
4404
  class XRButton {
4397
- constructor(sessionManager, startText = 'ENTER XR', endText = 'END XR', invalidText = 'XR NOT SUPPORTED', startSimulatorText = 'START SIMULATOR', enableSimulator = false, startSimulator = () => { }) {
4405
+ constructor(sessionManager, startText = 'ENTER XR', endText = 'END XR', invalidText = 'XR NOT SUPPORTED', startSimulatorText = 'START SIMULATOR', showEnterSimulatorButton = false, startSimulator = () => { }) {
4398
4406
  this.sessionManager = sessionManager;
4399
4407
  this.startText = startText;
4400
4408
  this.endText = endText;
@@ -4406,7 +4414,7 @@ class XRButton {
4406
4414
  this.xrButtonElement = document.createElement('button');
4407
4415
  this.domElement.id = XRBUTTON_WRAPPER_ID;
4408
4416
  this.createXRButtonElement();
4409
- if (enableSimulator) {
4417
+ if (showEnterSimulatorButton) {
4410
4418
  this.createSimulatorButton();
4411
4419
  }
4412
4420
  this.sessionManager.addEventListener(WebXRSessionEventType.UNSUPPORTED, this.showXRNotSupported.bind(this));
@@ -7414,6 +7422,7 @@ class Options {
7414
7422
  * Whether to use post-processing effects.
7415
7423
  */
7416
7424
  this.usePostprocessing = false;
7425
+ this.enableSimulator = true;
7417
7426
  /**
7418
7427
  * Configuration for the XR session button.
7419
7428
  */
@@ -7423,7 +7432,7 @@ class Options {
7423
7432
  endText: 'Exit XR',
7424
7433
  invalidText: 'XR Not Supported',
7425
7434
  startSimulatorText: 'Enter Simulator',
7426
- enableSimulator: true,
7435
+ showEnterSimulatorButton: false,
7427
7436
  // Whether to autostart the simulator even if WebXR is available.
7428
7437
  alwaysAutostartSimulator: false,
7429
7438
  };
@@ -10259,6 +10268,7 @@ class AudioListener extends Script {
10259
10268
  }
10260
10269
  }
10261
10270
 
10271
+ const DEFAULT_SCHEDULE_AHEAD_TIME = 1.0;
10262
10272
  class AudioPlayer extends Script {
10263
10273
  constructor(options = {}) {
10264
10274
  super();
@@ -10267,6 +10277,7 @@ class AudioPlayer extends Script {
10267
10277
  this.nextStartTime = 0;
10268
10278
  this.volume = 1.0;
10269
10279
  this.category = 'speech';
10280
+ this.scheduleAheadTime = DEFAULT_SCHEDULE_AHEAD_TIME;
10270
10281
  this.options = { sampleRate: 24000, channelCount: 1, ...options };
10271
10282
  if (options.category) {
10272
10283
  this.category = options.category;
@@ -10331,9 +10342,9 @@ class AudioPlayer extends Script {
10331
10342
  this.scheduleAudioBuffers();
10332
10343
  }
10333
10344
  scheduleAudioBuffers() {
10334
- const SCHEDULE_AHEAD_TIME = 0.2;
10335
10345
  while (this.audioQueue.length > 0 &&
10336
- this.nextStartTime <= this.audioContext.currentTime + SCHEDULE_AHEAD_TIME) {
10346
+ this.nextStartTime <=
10347
+ this.audioContext.currentTime + this.scheduleAheadTime) {
10337
10348
  const audioBuffer = this.audioQueue.shift();
10338
10349
  const currentTime = this.audioContext.currentTime;
10339
10350
  const startTime = Math.max(this.nextStartTime, currentTime);
@@ -14589,11 +14600,11 @@ class Core {
14589
14600
  // Sets up xrButton.
14590
14601
  let shouldAutostartSimulator = this.options.xrButton.alwaysAutostartSimulator;
14591
14602
  if (!shouldAutostartSimulator && options.xrButton.enabled) {
14592
- this.xrButton = new XRButton(this.webXRSessionManager, options.xrButton?.startText, options.xrButton?.endText, options.xrButton?.invalidText, options.xrButton?.startSimulatorText, options.xrButton?.enableSimulator, this.startSimulator.bind(this));
14603
+ this.xrButton = new XRButton(this.webXRSessionManager, options.xrButton?.startText, options.xrButton?.endText, options.xrButton?.invalidText, options.xrButton?.startSimulatorText, options.xrButton?.showEnterSimulatorButton, this.startSimulator.bind(this));
14593
14604
  document.body.appendChild(this.xrButton.domElement);
14594
14605
  }
14595
14606
  this.webXRSessionManager.addEventListener(WebXRSessionEventType.UNSUPPORTED, () => {
14596
- if (this.options.xrButton.enableSimulator) {
14607
+ if (this.options.enableSimulator) {
14597
14608
  this.xrButton?.domElement.remove();
14598
14609
  shouldAutostartSimulator = true;
14599
14610
  }
@@ -14716,7 +14727,6 @@ class Core {
14716
14727
  * scripts.
14717
14728
  */
14718
14729
  onXRSessionEnded() {
14719
- this.startSimulator();
14720
14730
  this.scriptsManager.onXRSessionEnded();
14721
14731
  }
14722
14732
  /**